diff --git a/kubernetes/services/ignite_config.xml b/kubernetes/services/ignite_config.xml index cbf1c5f5d..b7eddeddd 100644 --- a/kubernetes/services/ignite_config.xml +++ b/kubernetes/services/ignite_config.xml @@ -45,104 +45,104 @@ Copyright(c) 2020 Futurewei Cloud - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kubernetes/services/ignite_ip_config.xml b/kubernetes/services/ignite_ip_config.xml index 6e66078cd..7d8ea3230 100644 --- a/kubernetes/services/ignite_ip_config.xml +++ b/kubernetes/services/ignite_ip_config.xml @@ -38,9 +38,42 @@ Copyright(c) 2020 Futurewei Cloud + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kubernetes/services/ignite_port_config.xml b/kubernetes/services/ignite_port_config.xml index 40ee021bd..5110d5218 100644 --- a/kubernetes/services/ignite_port_config.xml +++ b/kubernetes/services/ignite_port_config.xml @@ -41,6 +41,45 @@ Copyright(c) 2020 Futurewei Cloud + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/pr663-config.xml b/lib/pr663-config.xml new file mode 100644 index 000000000..db7a55be5 --- /dev/null +++ b/lib/pr663-config.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 127.0.0.1:47500 + 127.0.0.1:47501 + 127.0.0.1:47502 + 127.0.0.1:47503 + 127.0.0.1:47504 + 127.0.0.1:47505 + 127.0.0.1:47506 + 127.0.0.1:47507 + 127.0.0.1:47508 + 127.0.0.1:47509 + + + + + + + + diff --git a/lib/src/main/java/com/futurewei/alcor/common/config/IgniteConfiguration.java b/lib/src/main/java/com/futurewei/alcor/common/config/IgniteConfiguration.java deleted file mode 100644 index 42bea39ab..000000000 --- a/lib/src/main/java/com/futurewei/alcor/common/config/IgniteConfiguration.java +++ /dev/null @@ -1,84 +0,0 @@ -/* -MIT License -Copyright(c) 2020 Futurewei Cloud - - Permission is hereby granted, - free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons - to whom the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -package com.futurewei.alcor.common.config; - -import com.futurewei.alcor.common.logging.Logger; -import com.futurewei.alcor.common.logging.LoggerFactory; -import org.apache.ignite.Ignition; -import org.apache.ignite.client.ClientException; -import org.apache.ignite.client.IgniteClient; -import org.apache.ignite.configuration.ClientConfiguration; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.util.Assert; - -import java.util.logging.Level; - -//@Configuration -//@ComponentScan("com.futurewei.common.service") -//@EntityScan("com.futurewei.common.entity") -//@ConditionalOnProperty(prefix = "ignite", name = "host") -@Deprecated -public class IgniteConfiguration { - private static final Logger logger = LoggerFactory.getLogger(); - - @Value("${ignite.host}") - private String host; - - @Value("${ignite.port}") - private Integer port; - - @Value("${ignite.key-store-path:#{null}}") - private String keyStorePath; - - @Value("${ignite.key-store-password:#{null}}") - private String keyStorePassword; - - @Value("${ignite.trust-store-path:#{null}}") - private String trustStorePath; - - @Value("${ignite.trust-store-password:#{null}}") - private String trustStorePassword; - - @Bean - public IgniteClient igniteClientInstance() { - ClientConfiguration cfg = new ClientConfiguration() - .setAddresses(host + ":" + port); - - if (keyStorePath != null && keyStorePassword != null && - trustStorePath != null && trustStorePassword != null) { - cfg.setSslClientCertificateKeyStorePath(keyStorePath) - .setSslClientCertificateKeyStorePassword(keyStorePassword) - .setSslTrustCertificateKeyStorePath(trustStorePath) - .setSslTrustCertificateKeyStorePassword(trustStorePassword); - } - - IgniteClient igniteClient = null; - - try { - igniteClient = Ignition.startClient(cfg); - } catch (ClientException e) { - logger.log(Level.WARNING, "Start client failed:" + e.getMessage()); - } catch (Exception e) { - logger.log(Level.WARNING, "Unexpected failure:" + e.getMessage()); - } - - Assert.notNull(igniteClient, "IgniteClient is null"); - - return igniteClient; - } -} diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/CacheFactory.java b/lib/src/main/java/com/futurewei/alcor/common/db/CacheFactory.java index 338938f57..4b55af778 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/CacheFactory.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/CacheFactory.java @@ -21,6 +21,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.common.db.redis.RedisCacheFactory; import org.apache.ignite.Ignite; import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.configuration.CacheConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; @@ -42,7 +43,11 @@ public ICache getCache(Class v, String cacheName) { return iCacheFactory.getCache(v, cacheName); } + public ICache getCache(Class v, CacheConfiguration cacheConfig) { + return iCacheFactory.getCache(v, cacheConfig); + } + public ICache getExpireCache(Class v, long timeout, TimeUnit timeUnit){ return iCacheFactory.getExpireCache(v, timeout, timeUnit); } -} +} \ No newline at end of file diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/ICacheFactory.java b/lib/src/main/java/com/futurewei/alcor/common/db/ICacheFactory.java index 5140d8aec..0a774a5a3 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/ICacheFactory.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/ICacheFactory.java @@ -16,6 +16,8 @@ free of charge, to any person obtaining a copy of this software and associated d package com.futurewei.alcor.common.db; +import org.apache.ignite.configuration.CacheConfiguration; + import java.util.concurrent.TimeUnit; public interface ICacheFactory { @@ -34,6 +36,14 @@ public interface ICacheFactory { */ ICache getCache(Class v, String cacheName); + ICache getCache(Class v, CacheConfiguration cacheConfig); + + /** + * get a cache with cache name and configuration + * @return + */ + ICache getCache(Class v, CacheConfiguration cacheConfig); + /** * get a cache with auto set expire time * @return @@ -48,4 +58,4 @@ public interface ICacheFactory { IDistributedLock getDistributedLock(Class t); Transaction getTransaction(); -} +} \ No newline at end of file diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteCacheFactory.java b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteCacheFactory.java index d12c9d6f6..0b4d0d0a2 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteCacheFactory.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteCacheFactory.java @@ -21,12 +21,12 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.common.db.IDistributedLock; import com.futurewei.alcor.common.db.Transaction; import org.apache.ignite.Ignite; +import org.apache.ignite.configuration.CacheConfiguration; import javax.cache.expiry.CreatedExpiryPolicy; import javax.cache.expiry.Duration; import javax.cache.expiry.ExpiryPolicy; import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; public class IgniteCacheFactory implements ICacheFactory { @@ -50,6 +50,10 @@ public ICache getCache(Class v, String cacheName) { return new IgniteDbCache<>(ignite, cacheName); } + @Override + public ICache + getCache(Class v, CacheConfiguration cacheConfig) { return new IgniteDbCache<>(ignite, cacheConfig); } + @Override public ICache getExpireCache(Class v, long timeout, TimeUnit timeUnit) { ExpiryPolicy ep = CreatedExpiryPolicy.factoryOf(new Duration(timeUnit, timeout)).create(); @@ -66,4 +70,4 @@ public Transaction getTransaction() { return new IgniteTransaction(ignite); } -} +} \ No newline at end of file diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteClientCacheFactory.java b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteClientCacheFactory.java index fa77ec7eb..c44b16ca8 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteClientCacheFactory.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteClientCacheFactory.java @@ -21,8 +21,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.common.db.IDistributedLock; import com.futurewei.alcor.common.db.Transaction; import org.apache.ignite.client.IgniteClient; -import org.apache.ignite.configuration.ClientConfiguration; - +import org.apache.ignite.configuration.CacheConfiguration; import javax.cache.expiry.CreatedExpiryPolicy; import javax.cache.expiry.Duration; import javax.cache.expiry.ExpiryPolicy; @@ -54,6 +53,11 @@ public ICache getCache(Class v, String cacheName) { return new IgniteClientDbCache<>(igniteClient, cacheName); } + @Override + public ICache getCache(Class v, CacheConfiguration cacheConfig) { + return new IgniteClientDbCache<>(igniteClient, cacheConfig); + } + @Override public ICache getExpireCache(Class v, long timeout, TimeUnit timeUnit) { ExpiryPolicy ep = CreatedExpiryPolicy.factoryOf(new Duration(timeUnit, timeout)).create(); @@ -69,4 +73,4 @@ public IDistributedLock getDistributedLock(Class t) { public Transaction getTransaction() { return new IgniteClientTransaction(igniteClient); } -} +} \ No newline at end of file diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteClientDbCache.java b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteClientDbCache.java index 52b160572..a07caf7bd 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteClientDbCache.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteClientDbCache.java @@ -28,8 +28,10 @@ free of charge, to any person obtaining a copy of this software and associated d import org.apache.ignite.cache.query.QueryCursor; import org.apache.ignite.cache.query.ScanQuery; import org.apache.ignite.client.ClientCache; +import org.apache.ignite.client.ClientCacheConfiguration; import org.apache.ignite.client.ClientException; import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.lang.IgniteBiPredicate; import org.springframework.util.Assert; @@ -61,12 +63,28 @@ public IgniteClientDbCache(IgniteClient igniteClient, String name) { this.transaction = new IgniteClientTransaction(igniteClient); } + public IgniteClientDbCache(IgniteClient igniteClient, CacheConfiguration cacheConfig) { + try { + ClientCacheConfiguration clientCacheConfig = new ClientCacheConfiguration(); + clientCacheConfig.setName(cacheConfig.getName()); + clientCacheConfig.setAtomicityMode(cacheConfig.getAtomicityMode()); + logger.log(Level.INFO, "Getting or creating cache " + clientCacheConfig.getName() + " AtomicityMode is " + clientCacheConfig.getAtomicityMode()); + this.cache = igniteClient.getOrCreateCache(clientCacheConfig); + logger.log(Level.INFO, "Retrieved cache " + this.cache.getConfiguration().getName() + " AtomicityMode is " + this.cache.getConfiguration().getAtomicityMode()); + } catch (ClientException e) { + logger.log(Level.ERROR, "Create cache for client " + cacheConfig.getName() + " failed:" + e.getMessage()); + } + + Assert.notNull(this.cache, "Create cache for client " + cacheConfig.getName() + "failed"); + this.transaction = new IgniteClientTransaction(igniteClient); + } + public IgniteClientDbCache(IgniteClient igniteClient, String name, ExpiryPolicy ep) { try { this.cache = igniteClient.getOrCreateCache(name).withExpirePolicy(ep); logger.log(Level.INFO, "Cache " + name + " AtomicityMode is " + this.cache.getConfiguration().getAtomicityMode()); } catch (ClientException e) { - logger.log(Level.WARNING, "Create cache for client " + name + " failed:" + e.getMessage()); + logger.log(Level.ERROR, "Create cache for client " + name + " failed:" + e.getMessage()); } Assert.notNull(this.cache, "Create cache for client " + name + "failed"); @@ -205,4 +223,4 @@ public long size() { public Transaction getTransaction() { return transaction; } -} \ No newline at end of file +} diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteConfiguration.java b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteConfiguration.java index 8d5dd3d0e..17fa9bd53 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteConfiguration.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteConfiguration.java @@ -17,7 +17,6 @@ free of charge, to any person obtaining a copy of this software and associated d package com.futurewei.alcor.common.db.ignite; import com.futurewei.alcor.common.db.ICacheFactory; -import com.futurewei.alcor.common.db.IDistributedLockFactory; import com.futurewei.alcor.common.logging.Logger; import com.futurewei.alcor.common.logging.LoggerFactory; import org.apache.ignite.Ignite; @@ -81,8 +80,8 @@ public class IgniteConfiguration { @Bean @Primary - public ICacheFactory igniteClientFactoryInstance(){ - if(thinClientEnable){ + public ICacheFactory igniteClientFactoryInstance() { + if (thinClientEnable) { return new IgniteClientCacheFactory(this.getThinIgniteClient(), this.tryLockInterval, this.expireTime); @@ -145,10 +144,10 @@ private Ignite getIgniteClient(String instanceName) { SslContextFactory factory = new SslContextFactory(); factory.setKeyStoreFilePath(keyStorePath); factory.setKeyStorePassword(keyStorePassword.toCharArray()); - if(trustStorePath != null && trustStorePassword != null) { + if (trustStorePath != null && trustStorePassword != null) { factory.setTrustStoreFilePath(trustStorePath); factory.setTrustStorePassword(trustStorePassword.toCharArray()); - }else{ + } else { factory.setTrustManagers(SslContextFactory.getDisabledTrustManager()); } diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteDbCache.java b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteDbCache.java index b62820281..f7b7aa5a7 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteDbCache.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/ignite/IgniteDbCache.java @@ -17,7 +17,6 @@ free of charge, to any person obtaining a copy of this software and associated d package com.futurewei.alcor.common.db.ignite; import com.futurewei.alcor.common.db.CacheException; -import com.futurewei.alcor.common.db.ICache; import com.futurewei.alcor.common.db.Transaction; import com.futurewei.alcor.common.db.ignite.query.ScanQueryBuilder; import com.futurewei.alcor.common.db.ignite.query.MapPredicate; @@ -31,6 +30,7 @@ free of charge, to any person obtaining a copy of this software and associated d import org.apache.ignite.cache.query.Query; import org.apache.ignite.cache.query.QueryCursor; import org.apache.ignite.cache.query.ScanQuery; +import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.lang.IgniteBiPredicate; import org.apache.ignite.transactions.TransactionException; import org.springframework.util.Assert; @@ -67,6 +67,21 @@ public IgniteDbCache(Ignite ignite, String name) { this.transaction = new IgniteTransaction(ignite); } + public IgniteDbCache(Ignite ignite, CacheConfiguration cfg) { + + try { + this.cache = ignite.getOrCreateCache(cfg); + } catch (javax.cache.CacheException e) { + this.cache = ignite.getOrCreateCache(cfg); + logger.log(Level.WARNING, "Create cache for client " + cfg + " failed:" + e.getMessage()); + } catch (Exception e) { + logger.log(Level.WARNING, "Unexpected failure:" + e.getMessage()); + } + + Assert.notNull(cache, "Create cache for client " + cfg + "failed"); + this.transaction = new IgniteTransaction(ignite); + } + public IgniteDbCache(Ignite client, String name, ExpiryPolicy ep) { try { @@ -162,19 +177,19 @@ public V get(IgniteBiPredicate igniteBiPredicate) throws CacheE QueryCursor> cursor = cache.withKeepBinary().query(ScanQueryBuilder.newScanQuery(igniteBiPredicate)); List> result = cursor.getAll(); - if(result.size() > 1){ + if (result.size() > 1) { throw new CacheException("more than one rows found!"); } - if(result.isEmpty()){ + if (result.isEmpty()) { return null; } E2 obj = result.get(0).getValue(); - if (obj instanceof BinaryObject){ - BinaryObject binaryObject = (BinaryObject)obj; + if (obj instanceof BinaryObject) { + BinaryObject binaryObject = (BinaryObject) obj; return binaryObject.deserialize(); - }else{ + } else { throw new CacheException("no support for object type:" + obj.getClass().getName()); } } @@ -190,16 +205,16 @@ public Map getAll(IgniteBiPredicate igniteBiPredicate) th QueryCursor> cursor = cache.withKeepBinary().query(ScanQueryBuilder.newScanQuery(igniteBiPredicate)); List> result = cursor.getAll(); - if(result.size() >= RESULT_THRESHOLD_SIZE){ + if (result.size() >= RESULT_THRESHOLD_SIZE) { throw new CacheException("too many rows found!"); } Map values = new HashMap<>(result.size()); - for(Cache.Entry entry: result){ + for (Cache.Entry entry : result) { E2 obj = entry.getValue(); - if (obj instanceof BinaryObject){ - BinaryObject binaryObject = (BinaryObject)obj; - values.put((K)entry.getKey(), binaryObject.deserialize()); - }else{ + if (obj instanceof BinaryObject) { + BinaryObject binaryObject = (BinaryObject) obj; + values.put((K) entry.getKey(), binaryObject.deserialize()); + } else { throw new CacheException("no support for object type:" + obj.getClass().getName()); } } diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/redis/RedisCacheFactory.java b/lib/src/main/java/com/futurewei/alcor/common/db/redis/RedisCacheFactory.java index 9ae4b842c..13f028e4b 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/redis/RedisCacheFactory.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/redis/RedisCacheFactory.java @@ -21,6 +21,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.common.db.IDistributedLock; import com.futurewei.alcor.common.db.Transaction; import com.futurewei.alcor.common.entity.TokenEntity; +import org.apache.ignite.configuration.CacheConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; @@ -53,13 +54,18 @@ public ICache getCache(Class v, String cacheName) { return new RedisCache<>(template, cacheName); } + @Override + public ICache getCache(Class v, CacheConfiguration cacheConfig) { + return null; + } + @Override public ICache getExpireCache(Class v, long timeout, TimeUnit timeUnit) { RedisTemplate template = getRedisTemplate(v); return new RedisExpireCache<>(template, timeout, timeUnit); } - private RedisTemplate getRedisTemplate(Class v){ + private RedisTemplate getRedisTemplate(Class v) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(lettuceConnectionFactory); @@ -86,4 +92,4 @@ public Transaction getTransaction() { template.setConnectionFactory(lettuceConnectionFactory); return new RedisTransaction(template); } -} +} \ No newline at end of file diff --git a/lib/src/main/java/com/futurewei/alcor/common/db/redis/RedisConfiguration.java b/lib/src/main/java/com/futurewei/alcor/common/db/redis/RedisConfiguration.java index f24a56b1b..32d8e126e 100644 --- a/lib/src/main/java/com/futurewei/alcor/common/db/redis/RedisConfiguration.java +++ b/lib/src/main/java/com/futurewei/alcor/common/db/redis/RedisConfiguration.java @@ -18,18 +18,14 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.common.db.ICacheFactory; -import com.futurewei.alcor.common.db.IDistributedLock; -import com.futurewei.alcor.common.db.IDistributedLockFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; -import org.springframework.data.redis.core.StringRedisTemplate; @Configuration @ComponentScan("com.futurewei.alcor.common.db") diff --git a/services/port_manager/src/main/java/com/futurewei/alcor/portmanager/repo/NeighborRepository.java b/services/port_manager/src/main/java/com/futurewei/alcor/portmanager/repo/NeighborRepository.java index f9650464b..7162dfbc7 100644 --- a/services/port_manager/src/main/java/com/futurewei/alcor/portmanager/repo/NeighborRepository.java +++ b/services/port_manager/src/main/java/com/futurewei/alcor/portmanager/repo/NeighborRepository.java @@ -22,8 +22,11 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.portmanager.entity.PortNeighbors; import com.futurewei.alcor.web.entity.dataplane.NeighborInfo; import com.futurewei.alcor.web.entity.port.PortEntity; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.configuration.CacheConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import java.util.List; import java.util.Map; @@ -37,6 +40,7 @@ public class NeighborRepository { private ICache neighborCache; private CacheFactory cacheFactory; + @Autowired public NeighborRepository(CacheFactory cacheFactory) { this.cacheFactory = cacheFactory; this.neighborCache= cacheFactory.getCache(PortNeighbors.class); @@ -53,16 +57,21 @@ public void createNeighbors(Map> neighbors) throws Ex .stream() .collect(Collectors.toMap(NeighborInfo::getPortIp, Function.identity())); - ICache neighborCache = this.cacheFactory.getCache( - NeighborInfo.class, getNeighborCacheName(entry.getKey())); + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getNeighborCacheName(entry.getKey())); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache neighborCache = cacheFactory.getCache(NeighborInfo.class, cfg); neighborCache.putAll(neighborMap); } } } public void updateNeighbors(PortEntity oldPortEntity, List newNeighbors) throws Exception { + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getNeighborCacheName(oldPortEntity.getVpcId())); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); ICache neighborCache = this.cacheFactory.getCache( - NeighborInfo.class, getNeighborCacheName(oldPortEntity.getVpcId())); + NeighborInfo.class, cfg); //Delete old neighborInfos if (oldPortEntity.getFixedIps() != null) { @@ -90,8 +99,11 @@ public void deleteNeighbors(PortEntity portEntity) throws Exception { .map(PortEntity.FixedIp::getIpAddress) .collect(Collectors.toList()); + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getNeighborCacheName(portEntity.getVpcId())); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); ICache neighborCache = this.cacheFactory.getCache( - NeighborInfo.class, getNeighborCacheName(portEntity.getVpcId())); + NeighborInfo.class, cfg); //Delete old neighborInfos for (String oldPortIp: oldPortIps) { @@ -102,8 +114,11 @@ public void deleteNeighbors(PortEntity portEntity) throws Exception { @DurationStatistics public Map getNeighbors(String vpcId) throws CacheException { + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getNeighborCacheName(vpcId)); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); ICache neighborCache = this.cacheFactory.getCache( - NeighborInfo.class, getNeighborCacheName(vpcId)); + NeighborInfo.class, cfg); return neighborCache.getAll(); } -} +} \ No newline at end of file diff --git a/services/private_ip_manager/src/main/java/com/futurewei/alcor/privateipmanager/repo/IpAddrRangeRepo.java b/services/private_ip_manager/src/main/java/com/futurewei/alcor/privateipmanager/repo/IpAddrRangeRepo.java index f6938bd5f..84e2f47de 100644 --- a/services/private_ip_manager/src/main/java/com/futurewei/alcor/privateipmanager/repo/IpAddrRangeRepo.java +++ b/services/private_ip_manager/src/main/java/com/futurewei/alcor/privateipmanager/repo/IpAddrRangeRepo.java @@ -29,6 +29,8 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.web.entity.ip.IpAddrRequest; import com.futurewei.alcor.web.entity.ip.IpAddrUpdateRequest; import com.futurewei.alcor.web.entity.ip.IpVersion; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.configuration.CacheConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -149,7 +151,7 @@ private IpAddrAlloc doAllocateIpAddr(String vpcId, int ipVersion, String ipAddr) } IpAddrAlloc ipAddrAlloc = null; - for (String rangeId: vpcIpRange.getRanges()) { + for (String rangeId : vpcIpRange.getRanges()) { if (ipAddrAlloc != null) { break; } @@ -164,8 +166,12 @@ private IpAddrAlloc doAllocateIpAddr(String vpcId, int ipVersion, String ipAddr) } try { + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(rangeId)); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(rangeId)); + cacheFactory.getCache(IpAddrAlloc.class, cfg); ipAddrAlloc = ipAddrRange.allocate(ipAddrCache, ipAddr); } catch (Exception e) { LOG.warn("Allocate ip address from {} failed", ipAddrRange.getId()); @@ -184,6 +190,7 @@ private IpAddrAlloc doAllocateIpAddr(String vpcId, int ipVersion, String ipAddr) /** * Allocate a ip address from IpAddrRange repository + * * @param request Assign ip address request * @return Ip address assigned from ip range * @throws Exception Db operation or ip address assignment exception @@ -199,6 +206,7 @@ public synchronized IpAddrAlloc allocateIpAddr(IpAddrRequest request) throws Exc /** * Assign multiple ip addresses from IpAddrRange repository + * * @param requests The number of ip addresses that will be assigned from each ip range * @return Number of ip addresses assigned each ip range * @throws Exception Db operation or ip address assignment exception @@ -209,14 +217,18 @@ public synchronized Map> allocateIpAddrBulk(Map> result = new HashMap<>(); try (Transaction tx = ipAddrRangeCache.getTransaction().start()) { - for (Map.Entry entry: requests.entrySet()) { + for (Map.Entry entry : requests.entrySet()) { IpAddrRange ipAddrRange = ipAddrRangeCache.get(entry.getKey()); if (ipAddrRange == null) { throw new IpRangeNotFoundException(); } + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(ipAddrRange.getId())); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(ipAddrRange.getId())); + cacheFactory.getCache(IpAddrAlloc.class, cfg); List ipAddrAllocs = ipAddrRange.allocateBulk(ipAddrCache, entry.getValue()); ipAddrRangeCache.put(ipAddrRange.getId(), ipAddrRange); @@ -236,8 +248,12 @@ private List doAllocateIpAddr(String rangeId, List i throw new IpRangeNotFoundException(); } + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(rangeId)); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(rangeId)); + cacheFactory.getCache(IpAddrAlloc.class, cfg); List ips = ipRequests.stream() .map(IpAddrRequest::getIp) @@ -258,7 +274,7 @@ private List doAllocateIpAddr(String vpcId, int ipVersion, List requestIps = ips.subList(0, ips.size()); - for (String rangeId: vpcIpRange.getRanges()) { + for (String rangeId : vpcIpRange.getRanges()) { if (result.size() == ips.size()) { break; } @@ -272,9 +288,12 @@ private List doAllocateIpAddr(String vpcId, int ipVersion, List ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(rangeId)); + cacheFactory.getCache(IpAddrAlloc.class, cfg); List ipAddrAllocs = ipAddrRange.allocateBulk(ipAddrCache, requestIps); @@ -298,7 +317,7 @@ public synchronized List allocateIpAddrBulk(Map> vpcIpv6Requests) throws Exception { List result = new ArrayList<>(); try (Transaction tx = ipAddrRangeCache.getTransaction().start()) { - allocateIpAddrBulkMethod(rangeRequests,vpcIpv4Requests,vpcIpv6Requests,result); + allocateIpAddrBulkMethod(rangeRequests, vpcIpv4Requests, vpcIpv6Requests, result); tx.commit(); } @@ -313,8 +332,12 @@ public synchronized void modifyIpAddrState(String rangeId, String ipAddr, String throw new IpRangeNotFoundException(); } + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(rangeId)); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(ipAddrRange.getId())); + cacheFactory.getCache(IpAddrAlloc.class, cfg); ipAddrRange.modifyIpAddrState(ipAddrCache, ipAddr, state); ipAddrRangeCache.put(ipAddrRange.getId(), ipAddrRange); @@ -326,7 +349,7 @@ public synchronized void modifyIpAddrState(String rangeId, String ipAddr, String @DurationStatistics public synchronized void releaseIpAddr(String rangeId, String ipAddr) throws Exception { try (Transaction tx = ipAddrRangeCache.getTransaction().start()) { - releaseIpAddrMethod(rangeId,ipAddr); + releaseIpAddrMethod(rangeId, ipAddr); tx.commit(); } } @@ -346,8 +369,12 @@ public synchronized IpAddrAlloc getIpAddr(String rangeId, String ipAddr) throws throw new IpRangeNotFoundException(); } + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(rangeId)); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(ipAddrRange.getId())); + cacheFactory.getCache(IpAddrAlloc.class, cfg); return ipAddrRange.getIpAddr(ipAddrCache, ipAddr); } @@ -359,8 +386,12 @@ public synchronized Collection getIpAddrBulk(String rangeId) throws throw new IpRangeNotFoundException(); } + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(rangeId)); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(ipAddrRange.getId())); + cacheFactory.getCache(IpAddrAlloc.class, cfg); return ipAddrRange.getIpAddrBulk(ipAddrCache); } @@ -437,8 +468,8 @@ public synchronized IpAddrRange getIpAddrRange(String rangeId) throws Exception } @DurationStatistics - public synchronized List updateIpAddr(IpAddrUpdateRequest request,Map> rangeToIpAddrList,Map> rangeRequests, - Map> vpcIpv4Requests,Map> vpcIpv6Requests) throws Exception { + public synchronized List updateIpAddr(IpAddrUpdateRequest request, Map> rangeToIpAddrList, Map> rangeRequests, + Map> vpcIpv4Requests, Map> vpcIpv6Requests) throws Exception { List result = null; try (Transaction tx = ipAddrRangeCache.getTransaction().start()) { @@ -452,7 +483,7 @@ public synchronized List updateIpAddr(IpAddrUpdateRequest request,M if (request.getNewIpAddrRequests().size() > 0) { result = new ArrayList<>(); if (request.getNewIpAddrRequests().size() > 1) { - allocateIpAddrBulkMethod(rangeRequests, vpcIpv4Requests, vpcIpv6Requests,result); + allocateIpAddrBulkMethod(rangeRequests, vpcIpv4Requests, vpcIpv6Requests, result); } else { IpAddrAlloc ipAddrAlloc = allocateIpAddrMethod(request.getNewIpAddrRequests().get(0)); result.add(ipAddrAlloc); @@ -463,15 +494,19 @@ public synchronized List updateIpAddr(IpAddrUpdateRequest request,M return result; } - private void releaseIpAddrBulkMethod(Map> requests) throws Exception{ - for (Map.Entry> entry: requests.entrySet()) { + private void releaseIpAddrBulkMethod(Map> requests) throws Exception { + for (Map.Entry> entry : requests.entrySet()) { IpAddrRange ipAddrRange = ipAddrRangeCache.get(entry.getKey()); if (ipAddrRange == null) { throw new IpRangeNotFoundException(); } + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(ipAddrRange.getId())); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(ipAddrRange.getId())); + cacheFactory.getCache(IpAddrAlloc.class, cfg); ipAddrRange.releaseBulk(ipAddrCache, entry.getValue()); ipAddrRangeCache.put(ipAddrRange.getId(), ipAddrRange); @@ -484,8 +519,12 @@ private void releaseIpAddrMethod(String rangeId, String ipAddr) throws Exception throw new IpRangeNotFoundException(); } + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(rangeId)); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(ipAddrRange.getId())); + cacheFactory.getCache(IpAddrAlloc.class, cfg); ipAddrRange.release(ipAddrCache, ipAddr); ipAddrRangeCache.put(ipAddrRange.getId(), ipAddrRange); @@ -494,11 +533,11 @@ private void releaseIpAddrMethod(String rangeId, String ipAddr) throws Exception private void allocateIpAddrBulkMethod(Map> rangeRequests, Map> vpcIpv4Requests, Map> vpcIpv6Requests, List result) throws Exception { - for (Map.Entry> entry: rangeRequests.entrySet()) { + for (Map.Entry> entry : rangeRequests.entrySet()) { result.addAll(doAllocateIpAddr(entry.getKey(), entry.getValue())); } - for (Map.Entry> entry: vpcIpv4Requests.entrySet()) { + for (Map.Entry> entry : vpcIpv4Requests.entrySet()) { result.addAll(doAllocateIpAddr(entry.getKey(), IpVersion.IPV4.getVersion(), entry.getValue().stream() @@ -506,7 +545,7 @@ private void allocateIpAddrBulkMethod(Map> rangeRequ .collect(Collectors.toList()))); } - for (Map.Entry> entry: vpcIpv6Requests.entrySet()) { + for (Map.Entry> entry : vpcIpv6Requests.entrySet()) { result.addAll(doAllocateIpAddr(entry.getKey(), IpVersion.IPV6.getVersion(), entry.getValue().stream() @@ -525,8 +564,13 @@ private IpAddrAlloc allocateIpAddrMethod(IpAddrRequest request) throws Exception if (ipAddrRange == null) { throw new IpRangeNotFoundException(); } + + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(getIpAddrCacheName(ipAddrRange.getId())); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ICache ipAddrCache = - cacheFactory.getCache(IpAddrAlloc.class, getIpAddrCacheName(request.getRangeId())); + cacheFactory.getCache(IpAddrAlloc.class, cfg); ipAddrAlloc = ipAddrRange.allocate(ipAddrCache, request.getIp()); ipAddrRangeCache.put(ipAddrRange.getId(), ipAddrRange); diff --git a/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/controller/SubnetController.java b/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/controller/SubnetController.java index b666120f3..b59b5d6ee 100644 --- a/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/controller/SubnetController.java +++ b/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/controller/SubnetController.java @@ -243,8 +243,12 @@ public SubnetWebJson createSubnetState(@PathVariable String projectId, @RequestB // Synchronous blocking CompletableFuture allFuture = CompletableFuture.allOf(vpcFuture, ipFuture); allFuture.join(); + VpcWebJson vpcResponse = vpcFuture.join(); + String ipRangeId = ipFuture.join(); - logger.info("Total processing time:" + (System.currentTimeMillis() - start) + "ms"); + logger.info("[createSubnetState] Verified VPC id:" + vpcResponse.toString()); + logger.info("[createSubnetState] Allocated ip range:" + ipRangeId); + logger.info("[createSubnetState] Time to verify VPC id and allocate ip range:" + (System.currentTimeMillis() - start) + "ms"); this.subnetDatabaseService.addSubnet(inSubnetEntity); @@ -270,10 +274,10 @@ public SubnetWebJson createSubnetState(@PathVariable String projectId, @RequestB } if (Ipv4AddrUtil.formatCheck(gatewayIp)) { - inSubnetEntity.setIpV4RangeId(ipFuture.join()); + inSubnetEntity.setIpV4RangeId(ipRangeId); inSubnetEntity.setIpVersion(4); } else { - inSubnetEntity.setIpV6RangeId(ipFuture.join()); + inSubnetEntity.setIpV6RangeId(ipRangeId); inSubnetEntity.setIpVersion(6); } @@ -467,18 +471,10 @@ public ResponseId deleteSubnetState(@PathVariable String projectId, @PathVariabl } String rangeId = null; - String ipV4RangeId = subnetEntity.getIpV4RangeId(); - String ipV6RangeId = subnetEntity.getIpV6RangeId(); - if (ipV4RangeId != null) { - rangeId = ipV4RangeId; + if (subnetEntity.getIpVersion() == 6) { + rangeId = subnetEntity.getIpV6RangeId(); } else { - rangeId = ipV6RangeId; - } - - // TODO: check if there is any gateway / non-gateway port for the subnet, waiting for PM new API - Boolean checkIfAnyNoneGatewayPortInSubnet = this.subnetService.checkIfAnyPortInSubnet(projectId, subnetId); - if (checkIfAnyNoneGatewayPortInSubnet) { - throw new HavePortInSubnet(); + rangeId = subnetEntity.getIpV4RangeId(); } // check if subnet bind any router @@ -494,7 +490,13 @@ public ResponseId deleteSubnetState(@PathVariable String projectId, @PathVariabl logger.warn(e.getMessage()); } - // TODO: delete gateway port in port manager. Temporary solution, need PM fix issue + // check if there is any non-gateway port for the subnet + boolean checkIfAnyNoneGatewayPortInSubnet = this.subnetService.checkIfAnyNonGatewayPortInSubnet(projectId, subnetEntity); + if (checkIfAnyNoneGatewayPortInSubnet) { + throw new HaveNonGatewayPortInSubnet(); + } + + // delete gateway port in port manager GatewayPortDetail gatewayPortDetail = subnetEntity.getGatewayPortDetail(); if (gatewayPortDetail != null) { try{ @@ -512,7 +514,7 @@ public ResponseId deleteSubnetState(@PathVariable String projectId, @PathVariabl this.subnetDatabaseService.deleteSubnet(subnetId); - } catch (ParameterNullOrEmptyException | HavePortInSubnet | SubnetBindRouter e) { + } catch (ParameterNullOrEmptyException | HaveNonGatewayPortInSubnet | SubnetBindRouter e) { logger.error(e.getMessage()); throw new Exception(e); } diff --git a/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/exception/HavePortInSubnet.java b/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/exception/HaveNonGatewayPortInSubnet.java similarity index 91% rename from services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/exception/HavePortInSubnet.java rename to services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/exception/HaveNonGatewayPortInSubnet.java index 7fe245e09..b1f37f369 100644 --- a/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/exception/HavePortInSubnet.java +++ b/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/exception/HaveNonGatewayPortInSubnet.java @@ -18,6 +18,6 @@ free of charge, to any person obtaining a copy of this software and associated d import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; -@ResponseStatus(code= HttpStatus.CONFLICT, reason="There is some ports in the subnet, we can Not delete subnet") -public class HavePortInSubnet extends Exception { +@ResponseStatus(code= HttpStatus.CONFLICT, reason="There is some customer ports in the subnet, we can Not delete subnet") +public class HaveNonGatewayPortInSubnet extends Exception { } diff --git a/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/service/SubnetService.java b/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/service/SubnetService.java index d133bf55b..727c18866 100644 --- a/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/service/SubnetService.java +++ b/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/service/SubnetService.java @@ -69,7 +69,7 @@ public void fallbackOperation (AtomicReference routeResponseAtomic public void deleteSubnetIdInVpc (String subnetId, String projectId, String vpcId) throws Exception; // check if there is any port in this subnet - public boolean checkIfAnyPortInSubnet (String projectId, String subnetId) throws SubnetIdIsNull; + public boolean checkIfAnyNonGatewayPortInSubnet(String projectId, SubnetEntity subnetEntity) throws SubnetIdIsNull; // check if subnet bind any routes public boolean checkIfSubnetBindAnyRouter(SubnetEntity subnetEntity); diff --git a/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/service/implement/SubnetServiceImp.java b/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/service/implement/SubnetServiceImp.java index e58ccbd71..1d1eae341 100644 --- a/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/service/implement/SubnetServiceImp.java +++ b/services/subnet_manager/src/main/java/com/futurewei/alcor/subnet/service/implement/SubnetServiceImp.java @@ -39,6 +39,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.web.entity.route.*; import com.futurewei.alcor.web.entity.subnet.*; import com.futurewei.alcor.web.entity.vpc.VpcWebJson; +import io.netty.util.internal.StringUtil; import org.apache.commons.net.util.SubnetUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -304,12 +305,15 @@ public void deleteSubnetIdInVpc(String subnetId, String projectId, String vpcId) } @Override - public boolean checkIfAnyPortInSubnet(String projectId, String subnetId) throws SubnetIdIsNull { - if (subnetId == null) { + public boolean checkIfAnyNonGatewayPortInSubnet(String projectId, SubnetEntity subnetEntity) throws SubnetIdIsNull { + if (subnetEntity == null || StringUtil.isNullOrEmpty(subnetEntity.getId())) { throw new SubnetIdIsNull(); } - String portManagerServiceUrl = portUrl + "project/" + projectId + "/subnet-port-count/" + subnetId; - int portCount = restTemplate.getForObject(portManagerServiceUrl, Integer.class); + + String portManagerServiceUrl = portUrl + "project/" + projectId + "/subnet-port-count/" + subnetEntity.getId(); + int portCount = restTemplate.getForObject(portManagerServiceUrl, Integer.class); + + logger.info("[checkIfAnyNonGatewayPortInSubnet]: portCount == " + portCount + " && subnetEntity.getGatewayPortId() = " + subnetEntity.getGatewayPortId()); if (portCount == 0) { return false; } @@ -321,7 +325,7 @@ public boolean checkIfAnyPortInSubnet(String projectId, String subnetId) throws public boolean checkIfSubnetBindAnyRouter(SubnetEntity subnetEntity) { String attachedRouterId = subnetEntity.getAttachedRouterId(); - if (attachedRouterId == null || attachedRouterId.equals("")){ + if (attachedRouterId == null || attachedRouterId.equals("")) { return false; } @@ -330,7 +334,7 @@ public boolean checkIfSubnetBindAnyRouter(SubnetEntity subnetEntity) { @Override @DurationStatistics - public boolean checkIfCidrOverlap(String cidr,String projectId, String vpcId) throws FallbackException, ResourceNotFoundException, ResourcePersistenceException, CidrNotWithinNetworkCidr, CidrOverlapWithOtherSubnets { + public boolean checkIfCidrOverlap(String cidr, String projectId, String vpcId) throws FallbackException, ResourceNotFoundException, ResourcePersistenceException, CidrNotWithinNetworkCidr, CidrOverlapWithOtherSubnets { // get vpc and check with vpc cidr VpcWebJson vpcWebJson = verifyVpcId(projectId, vpcId); @@ -341,8 +345,7 @@ public boolean checkIfCidrOverlap(String cidr,String projectId, String vpcId) th throw new CidrNotWithinNetworkCidr(); } } - - + // get subnet list and check with subnets cidr List subnetIds = vpcWebJson.getNetwork().getSubnets(); for (String subnetId : subnetIds) { @@ -552,7 +555,7 @@ public void deleteIPRangeInPIM(String rangeId) { return; } - String ipManagerCreateRangeUrl = ipUrl + "range/"+ rangeId; + String ipManagerCreateRangeUrl = ipUrl + "range/" + rangeId; restTemplate.delete(ipManagerCreateRangeUrl); } diff --git a/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/controller/VpcController.java b/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/controller/VpcController.java index 746d44731..9e9541df5 100644 --- a/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/controller/VpcController.java +++ b/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/controller/VpcController.java @@ -68,7 +68,7 @@ public class VpcController { * @return vpc state * @throws Exception */ - @Rbac(resource ="vpc") + @Rbac(resource = "vpc") @FieldFilter(type = VpcEntity.class) @RequestMapping( method = GET, @@ -114,7 +114,7 @@ public VpcsWebJson createVpcStateBulk(@PathVariable String projectid, @RequestBo * @return vpc state * @throws Exception */ - @Rbac(resource ="vpc") + @Rbac(resource = "vpc") @RequestMapping( method = POST, value = {"/project/{projectid}/vpcs"}) @@ -194,7 +194,7 @@ public VpcWebJson createVpcState(@PathVariable String projectid, @RequestBody Vp * @return vpc state * @throws Exception */ - @Rbac(resource ="vpc") + @Rbac(resource = "vpc") @RequestMapping( method = PUT, value = {"/project/{projectid}/vpcs/{vpcid}"}) @@ -252,7 +252,7 @@ public VpcWebJson updateVpcStateByVpcId(@PathVariable String projectid, @PathVar * @return network id * @throws Exception */ - @Rbac(resource ="vpc") + @Rbac(resource = "vpc") @RequestMapping( method = DELETE, value = {"/project/{projectid}/vpcs/{vpcid}"}) @@ -290,7 +290,7 @@ public ResponseId deleteVpcStateByVpcId(@PathVariable String projectid, @PathVar * @return Map * @throws Exception */ - @Rbac(resource ="vpc") + @Rbac(resource = "vpc") @FieldFilter(type = VpcEntity.class) @RequestMapping( method = GET, @@ -298,8 +298,8 @@ public ResponseId deleteVpcStateByVpcId(@PathVariable String projectid, @PathVar @DurationStatistics public VpcsWebJson getVpcStatesByProjectId(@PathVariable String projectId) throws Exception { Map vpcStates = null; - Map requestParams = (Map)request.getAttribute(QUERY_ATTR_HEADER); - requestParams = requestParams == null ? request.getParameterMap():requestParams; + Map requestParams = (Map) request.getAttribute(QUERY_ATTR_HEADER); + requestParams = requestParams == null ? request.getParameterMap() : requestParams; Map queryParams = ControllerUtil.transformUrlPathParams(requestParams, VpcEntity.class); @@ -339,6 +339,7 @@ public Map getVpcCountAndAllVpcStates() throws CacheException { /** * Updates a network with subnet id + * * @param projectid * @param vpcid * @param subnetid @@ -381,11 +382,11 @@ public VpcWebJson addSubnetIdToVpcState(@PathVariable String projectid, @PathVar } return new VpcWebJson(inVpcState); - } /** * delete subnet id in a network + * * @param projectid * @param vpcid * @param subnetid @@ -398,35 +399,19 @@ public VpcWebJson addSubnetIdToVpcState(@PathVariable String projectid, @PathVar @DurationStatistics public VpcWebJson deleteSubnetIdInVpcState(@PathVariable String projectid, @PathVariable String vpcid, @PathVariable String subnetid) throws Exception { - VpcEntity inVpcState = new VpcEntity(); + VpcEntity inVpcState = null; try { RestPreconditionsUtil.verifyParameterNotNullorEmpty(projectid); RestPreconditionsUtil.verifyParameterNotNullorEmpty(vpcid); RestPreconditionsUtil.verifyParameterNotNullorEmpty(subnetid); - inVpcState = this.vpcDatabaseService.getByVpcId(vpcid); - if (inVpcState == null) { - throw new ResourceNotFoundException("Vpc not found : " + vpcid); - } + inVpcState = this.vpcDatabaseService.deleteSubnetIdInVpc(vpcid, subnetid); - List subnets = inVpcState.getSubnets(); - if (subnets == null || !subnets.contains(subnetid)) { - return new VpcWebJson(inVpcState); - } - subnets.remove(subnetid); - - inVpcState.setSubnets(subnets); - - this.vpcDatabaseService.addVpc(inVpcState); - - inVpcState = this.vpcDatabaseService.getByVpcId(vpcid); - - } catch (ParameterNullOrEmptyException e) { + } catch (Exception e) { throw new Exception(e); } return new VpcWebJson(inVpcState); - } } \ No newline at end of file diff --git a/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/dao/VpcRepository.java b/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/dao/VpcRepository.java index d02bc480e..b15491599 100644 --- a/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/dao/VpcRepository.java +++ b/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/dao/VpcRepository.java @@ -18,6 +18,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.common.db.CacheException; import com.futurewei.alcor.common.db.CacheFactory; import com.futurewei.alcor.common.db.ICache; +import com.futurewei.alcor.common.db.Transaction; import com.futurewei.alcor.common.db.repo.ICacheRepository; import com.futurewei.alcor.common.logging.Logger; import com.futurewei.alcor.common.logging.LoggerFactory; @@ -43,6 +44,14 @@ public ICache getCache() { private ICache cache; + public Transaction startTransaction() throws CacheException { + return cache.getTransaction().start(); + } + + public void commitTransaction() throws CacheException { + cache.getTransaction().commit(); + } + @Autowired public VpcRepository(CacheFactory cacheFactory) { cache = cacheFactory.getCache(VpcEntity.class); diff --git a/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/service/Impl/VpcDatabaseServiceImpl.java b/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/service/Impl/VpcDatabaseServiceImpl.java index 207188377..17a89b713 100644 --- a/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/service/Impl/VpcDatabaseServiceImpl.java +++ b/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/service/Impl/VpcDatabaseServiceImpl.java @@ -17,16 +17,20 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.common.db.CacheException; import com.futurewei.alcor.common.db.ICache; +import com.futurewei.alcor.common.db.Transaction; import com.futurewei.alcor.common.exception.DatabasePersistenceException; +import com.futurewei.alcor.common.exception.ResourceNotFoundException; import com.futurewei.alcor.common.stats.DurationStatistics; import com.futurewei.alcor.vpcmanager.dao.VpcRepository; import com.futurewei.alcor.vpcmanager.service.VpcDatabaseService; import com.futurewei.alcor.web.entity.vpc.VpcEntity; +import com.futurewei.alcor.web.entity.vpc.VpcWebJson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; import java.util.Map; @Service @@ -42,7 +46,7 @@ public class VpcDatabaseServiceImpl implements VpcDatabaseService { public VpcEntity getByVpcId(String vpcId) { try { return this.vpcRepository.findItem(vpcId); - }catch (Exception e) { + } catch (Exception e) { return null; } } @@ -75,6 +79,38 @@ public void deleteVpc(String id) throws CacheException { this.vpcRepository.deleteItem(id); } + @Override + public VpcEntity deleteSubnetIdInVpc(String vpcId, String subnetId) throws Exception { + + VpcEntity currentVpcState = null; + + try (Transaction tx = this.vpcRepository.startTransaction()) { + + currentVpcState = getByVpcId(vpcId); + if (currentVpcState == null) { + throw new ResourceNotFoundException("Vpc not found : " + vpcId); + } + + List subnets = currentVpcState.getSubnets(); + if (subnets == null || !subnets.contains(subnetId)) { + return currentVpcState; + } + + subnets.remove(subnetId); + currentVpcState.setSubnets(subnets); + addVpc(currentVpcState); + + tx.commit(); + } catch (ResourceNotFoundException | DatabasePersistenceException | CacheException e) { + throw e; + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + + return currentVpcState; + } + @Override @DurationStatistics public ICache getCache() { diff --git a/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/service/VpcDatabaseService.java b/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/service/VpcDatabaseService.java index 894b7dc4e..f3c67de75 100644 --- a/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/service/VpcDatabaseService.java +++ b/services/vpc_manager/src/main/java/com/futurewei/alcor/vpcmanager/service/VpcDatabaseService.java @@ -31,6 +31,7 @@ public interface VpcDatabaseService { public Map getAllVpcs (Map queryParams) throws CacheException; public void addVpc (VpcEntity vpcState) throws DatabasePersistenceException; public void deleteVpc (String id) throws CacheException; + public VpcEntity deleteSubnetIdInVpc(String vpcId, String subnetId) throws Exception; public ICache getCache (); } diff --git a/web/src/main/java/com/futurewei/alcor/web/entity/subnet/SubnetEntity.java b/web/src/main/java/com/futurewei/alcor/web/entity/subnet/SubnetEntity.java index 783db0a6f..75c99af2a 100644 --- a/web/src/main/java/com/futurewei/alcor/web/entity/subnet/SubnetEntity.java +++ b/web/src/main/java/com/futurewei/alcor/web/entity/subnet/SubnetEntity.java @@ -150,6 +150,7 @@ public SubnetEntity(String projectId, String vpcId, String id, String name, Stri super(projectId, id, name, null); this.vpcId = vpcId; this.cidr = cidr; + this.ipVersion = 4; } public SubnetEntity(String projectId, String id, String name, String description, String vpcId,