From efe828ec7619ce34dcb725039e0f65f73c26ca3c Mon Sep 17 00:00:00 2001 From: chenpiaoping <60864880+chenpiaoping@users.noreply.github.com> Date: Wed, 25 Mar 2020 21:21:04 +0800 Subject: [PATCH] Replace Redis with Apache Ignite for in memory cache and db (#129) * Add ignite cache * Add db modue * Fix test case failure * Add transaction for db cahche and SSL for ignite connection * SSL for ignite connection is optional * Set the default value of ignite's SSL configuration to null * Rename the directory cache.repo to db.repo --- pom.xml | 6 + .../controller/app/AlcorControllerApp.java | 2 +- .../alcor/controller/db/CacheFactory.java | 70 ++++++++ .../futurewei/alcor/controller/db/ICache.java | 37 ++++ .../Transaction.java} | 15 +- .../controller/db/ignite/IgniteCache.java | 130 ++++++++++++++ .../db/ignite/IgniteConfiguration.java | 88 ++++++++++ .../db/ignite/IgniteTransaction.java | 79 +++++++++ .../alcor/controller/db/redis/RedisCache.java | 110 ++++++++++++ .../redis}/RedisConfiguration.java | 6 +- .../controller/db/redis/RedisTransaction.java | 68 ++++++++ .../controller/db/repo/ICacheRepository.java | 32 ++++ .../repo/PortRedisRepository.java | 2 +- .../controller/db/repo/PortRepository.java | 70 ++++++++ .../repo/SubnetRedisRepository.java | 2 +- .../controller/db/repo/SubnetRepository.java | 71 ++++++++ .../repo/VpcRedisRepository.java | 2 +- .../controller/db/repo/VpcRepository.java | 74 ++++++++ .../controller/exception/CacheException.java | 20 +++ .../controller/model/CustomerResource.java | 4 +- .../alcor/controller/web/DebugController.java | 4 +- .../controller/web/DebugVpcController.java | 164 ++++++++++++++++++ .../alcor/controller/web/PortController.java | 6 +- .../controller/web/SubnetController.java | 4 +- .../alcor/controller/web/VpcController.java | 2 +- src/resources/application.properties | 7 + src/resources/example_keystore.jks | Bin 0 -> 347 bytes src/resources/keystore.jks | Bin 0 -> 2218 bytes src/resources/truststore.jks | Bin 0 -> 930 bytes 29 files changed, 1051 insertions(+), 24 deletions(-) create mode 100644 src/com/futurewei/alcor/controller/db/CacheFactory.java create mode 100644 src/com/futurewei/alcor/controller/db/ICache.java rename src/com/futurewei/alcor/controller/{cache/repo/ICacheRepository.java => db/Transaction.java} (69%) create mode 100644 src/com/futurewei/alcor/controller/db/ignite/IgniteCache.java create mode 100644 src/com/futurewei/alcor/controller/db/ignite/IgniteConfiguration.java create mode 100644 src/com/futurewei/alcor/controller/db/ignite/IgniteTransaction.java create mode 100644 src/com/futurewei/alcor/controller/db/redis/RedisCache.java rename src/com/futurewei/alcor/controller/{cache/config => db/redis}/RedisConfiguration.java (96%) create mode 100644 src/com/futurewei/alcor/controller/db/redis/RedisTransaction.java create mode 100644 src/com/futurewei/alcor/controller/db/repo/ICacheRepository.java rename src/com/futurewei/alcor/controller/{cache => db}/repo/PortRedisRepository.java (97%) create mode 100644 src/com/futurewei/alcor/controller/db/repo/PortRepository.java rename src/com/futurewei/alcor/controller/{cache => db}/repo/SubnetRedisRepository.java (97%) create mode 100644 src/com/futurewei/alcor/controller/db/repo/SubnetRepository.java rename src/com/futurewei/alcor/controller/{cache => db}/repo/VpcRedisRepository.java (97%) create mode 100644 src/com/futurewei/alcor/controller/db/repo/VpcRepository.java create mode 100644 src/com/futurewei/alcor/controller/exception/CacheException.java create mode 100644 src/com/futurewei/alcor/controller/web/DebugVpcController.java create mode 100644 src/resources/example_keystore.jks create mode 100644 src/resources/keystore.jks create mode 100644 src/resources/truststore.jks diff --git a/pom.xml b/pom.xml index f02b40e7..8ec87e31 100644 --- a/pom.xml +++ b/pom.xml @@ -130,6 +130,12 @@ spring-kafka-test test + + + org.apache.ignite + ignite-core + 2.8.0 + diff --git a/src/com/futurewei/alcor/controller/app/AlcorControllerApp.java b/src/com/futurewei/alcor/controller/app/AlcorControllerApp.java index bd1a0e37..1b6e509b 100644 --- a/src/com/futurewei/alcor/controller/app/AlcorControllerApp.java +++ b/src/com/futurewei/alcor/controller/app/AlcorControllerApp.java @@ -18,7 +18,7 @@ import com.futurewei.alcor.controller.app.onebox.OneBoxConfig; import com.futurewei.alcor.controller.app.onebox.OneBoxUtil; -import com.futurewei.alcor.controller.cache.config.RedisConfiguration; +import com.futurewei.alcor.controller.db.redis.RedisConfiguration; import com.futurewei.alcor.controller.logging.Logger; import com.futurewei.alcor.controller.logging.LoggerFactory; import com.futurewei.alcor.controller.model.HostInfo; diff --git a/src/com/futurewei/alcor/controller/db/CacheFactory.java b/src/com/futurewei/alcor/controller/db/CacheFactory.java new file mode 100644 index 00000000..1a1a9c3a --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/CacheFactory.java @@ -0,0 +1,70 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db; + +import com.futurewei.alcor.controller.db.ignite.IgniteCache; +import com.futurewei.alcor.controller.db.redis.RedisCache; +import org.apache.ignite.client.IgniteClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.stereotype.Component; + + +@ComponentScan +@Component +public class CacheFactory { + @Autowired(required = false) + private IgniteClient igniteClient; + + @Autowired + LettuceConnectionFactory lettuceConnectionFactory; + + @Bean + CacheFactory cacheFactoryInstance() { + return new CacheFactory(); + } + + private ICache getIgniteCache(String cacheName) { + return new IgniteCache<>(igniteClient, cacheName); + } + + public ICache getRedisCache(Class v, String cacheName) { + + RedisTemplate template = new RedisTemplate(); + template.setConnectionFactory(lettuceConnectionFactory); + template.setKeySerializer(new StringRedisSerializer()); + + template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(v)); + template.setValueSerializer(new Jackson2JsonRedisSerializer<>(v)); + template.afterPropertiesSet(); + + return new RedisCache<>(template, cacheName); + } + + public ICache getCache(Class v) { + if (igniteClient != null) { + return getIgniteCache(v.getName()); + } + + return getRedisCache(v, v.getName()); + } +} diff --git a/src/com/futurewei/alcor/controller/db/ICache.java b/src/com/futurewei/alcor/controller/db/ICache.java new file mode 100644 index 00000000..73cd1e4f --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/ICache.java @@ -0,0 +1,37 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db; + +import com.futurewei.alcor.controller.exception.CacheException; + +import java.util.Map; + +public interface ICache { + V get(K var1) throws CacheException; + + void put(K var1, V var2) throws CacheException; + + boolean containsKey(K var1) throws CacheException; + + Map getAll() throws CacheException; + + void putAll(Map var1) throws CacheException; + + boolean remove(K var1) throws CacheException; + + Transaction getTransaction(); +} diff --git a/src/com/futurewei/alcor/controller/cache/repo/ICacheRepository.java b/src/com/futurewei/alcor/controller/db/Transaction.java similarity index 69% rename from src/com/futurewei/alcor/controller/cache/repo/ICacheRepository.java rename to src/com/futurewei/alcor/controller/db/Transaction.java index a037849a..b27048bd 100644 --- a/src/com/futurewei/alcor/controller/cache/repo/ICacheRepository.java +++ b/src/com/futurewei/alcor/controller/db/Transaction.java @@ -14,17 +14,16 @@ limitations under the License. */ -package com.futurewei.alcor.controller.cache.repo; +package com.futurewei.alcor.controller.db; -import java.util.Map; +import com.futurewei.alcor.controller.exception.CacheException; -public interface ICacheRepository { +public interface Transaction { + void start() throws CacheException; - T findItem(String id); + void commit() throws CacheException; - Map findAllItems(); + void rollback() throws CacheException; - void addItem(T newItem); - - void deleteItem(String id); + void close(); } diff --git a/src/com/futurewei/alcor/controller/db/ignite/IgniteCache.java b/src/com/futurewei/alcor/controller/db/ignite/IgniteCache.java new file mode 100644 index 00000000..4809510b --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/ignite/IgniteCache.java @@ -0,0 +1,130 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.ignite; + +import com.futurewei.alcor.controller.db.ICache; +import com.futurewei.alcor.controller.db.Transaction; +import com.futurewei.alcor.controller.exception.CacheException; +import com.futurewei.alcor.controller.logging.Logger; +import com.futurewei.alcor.controller.logging.LoggerFactory; +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.client.ClientCache; +import org.apache.ignite.client.ClientException; +import org.apache.ignite.client.IgniteClient; +import org.springframework.util.Assert; + +import javax.cache.Cache; +import java.util.Map; +import java.util.logging.Level; +import java.util.stream.Collectors; + + +public class IgniteCache implements ICache { + private static final Logger logger = LoggerFactory.getLogger(); + private ClientCache cache; + private IgniteClient igniteClient; + private IgniteTransaction transaction; + + public IgniteCache(IgniteClient igniteClient, String name) { + this.igniteClient = igniteClient; + + try { + cache = igniteClient.getOrCreateCache(name); + } + catch (ClientException e) { + logger.log(Level.WARNING, "Create cache for vpc failed:" + e.getMessage()); + } + catch (Exception e) { + logger.log(Level.WARNING, "Unexpected failure:" + e.getMessage()); + } + + transaction = new IgniteTransaction(igniteClient); + + Assert.notNull(igniteClient, "Create cache for vpc failed"); + } + + @Override + public V get(K key) throws CacheException { + try { + return cache.get(key); + }catch (ClientException e) { + logger.log(Level.WARNING, "IgniteCache get operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public void put(K key, V value) throws CacheException { + try { + cache.put(key, value); + }catch (ClientException e) { + logger.log(Level.WARNING, "IgniteCache put operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public boolean containsKey(K key) throws CacheException { + try { + return cache.containsKey(key); + }catch (ClientException e) { + logger.log(Level.WARNING, "IgniteCache containsKey operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public Map getAll() throws CacheException { + Query> qry = new ScanQuery(); + + try { + QueryCursor> cur = cache.query(qry); + return cur.getAll().stream().collect(Collectors + .toMap(Cache.Entry::getKey, Cache.Entry::getValue)); + } catch (Exception e) { + logger.log(Level.WARNING, "IgniteCache getAll operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public void putAll(Map items) throws CacheException { + try { + cache.putAll(items); + }catch (ClientException e) { + logger.log(Level.WARNING, "IgniteCache putAll operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public boolean remove(K key) throws CacheException { + try { + return cache.remove(key); + }catch (ClientException e) { + logger.log(Level.WARNING, "IgniteCache remove operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public Transaction getTransaction() { + return transaction; + } +} diff --git a/src/com/futurewei/alcor/controller/db/ignite/IgniteConfiguration.java b/src/com/futurewei/alcor/controller/db/ignite/IgniteConfiguration.java new file mode 100644 index 00000000..a35b52ec --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/ignite/IgniteConfiguration.java @@ -0,0 +1,88 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.ignite; + +import com.futurewei.alcor.controller.logging.Logger; +import com.futurewei.alcor.controller.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.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.util.Assert; +import java.util.logging.Level; + +@Configuration +@ComponentScan("com.futurewei.alcor.controller.db") +@EntityScan("com.futurewei.alcor.controller.db") +@ConditionalOnProperty(prefix = "ignite", name = "host") +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/src/com/futurewei/alcor/controller/db/ignite/IgniteTransaction.java b/src/com/futurewei/alcor/controller/db/ignite/IgniteTransaction.java new file mode 100644 index 00000000..0001d0bf --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/ignite/IgniteTransaction.java @@ -0,0 +1,79 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.ignite; + +import com.futurewei.alcor.controller.exception.CacheException; +import com.futurewei.alcor.controller.db.Transaction; +import com.futurewei.alcor.controller.logging.Logger; +import com.futurewei.alcor.controller.logging.LoggerFactory; +import org.apache.ignite.client.ClientException; +import org.apache.ignite.client.ClientTransaction; +import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.internal.client.thin.ClientServerError; + +import java.util.logging.Level; + +public class IgniteTransaction implements Transaction { + private static final Logger logger = LoggerFactory.getLogger(); + + private IgniteClient igniteClient; + private ClientTransaction clientTransaction; + + public IgniteTransaction(IgniteClient igniteClient) { + this.igniteClient = igniteClient; + } + + public void start() throws CacheException { + try { + clientTransaction = igniteClient.transactions().txStart(); + } catch (ClientServerError e) { + logger.log(Level.WARNING, "IgniteTransaction start error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } catch (ClientException e) { + logger.log(Level.WARNING, "IgniteTransaction start error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + public void commit() throws CacheException { + try { + clientTransaction.commit(); + } catch (ClientServerError e) { + logger.log(Level.WARNING, "IgniteTransaction commit error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } catch (ClientException e) { + logger.log(Level.WARNING, "IgniteTransaction commit error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + public void rollback() throws CacheException { + try { + clientTransaction.rollback(); + } catch (ClientServerError e) { + logger.log(Level.WARNING, "IgniteTransaction rollback error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } catch (ClientException e) { + logger.log(Level.WARNING, "IgniteTransaction rollback error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + public void close() { + clientTransaction.close(); + } +} diff --git a/src/com/futurewei/alcor/controller/db/redis/RedisCache.java b/src/com/futurewei/alcor/controller/db/redis/RedisCache.java new file mode 100644 index 00000000..3ae1668b --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/redis/RedisCache.java @@ -0,0 +1,110 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.redis; + +import com.futurewei.alcor.controller.db.ICache; +import com.futurewei.alcor.controller.db.Transaction; +import com.futurewei.alcor.controller.exception.CacheException; +import com.futurewei.alcor.controller.logging.Logger; +import com.futurewei.alcor.controller.logging.LoggerFactory; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.Map; +import java.util.logging.Level; + +public class RedisCache implements ICache { + private static final Logger logger = LoggerFactory.getLogger(); + + private RedisTemplate redisTemplate; + private HashOperations hashOperations; + private RedisTransaction transaction; + private String name; + + public RedisCache(RedisTemplate redisTemplate, String name) { + this.redisTemplate = redisTemplate; + hashOperations = redisTemplate.opsForHash(); + this.name = name; + + transaction = new RedisTransaction(redisTemplate); + } + + @Override + public V get(K key) throws CacheException { + try { + return (V) hashOperations.get(name, key); + } catch (Exception e) { + logger.log(Level.WARNING, "RedisCache get operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public void put(K key, V value) throws CacheException { + try { + hashOperations.put(name, key, value); + } catch (Exception e) { + logger.log(Level.WARNING, "RedisCache put operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public boolean containsKey(K key) throws CacheException { + try { + return hashOperations.hasKey(name, key); + } catch (Exception e) { + logger.log(Level.WARNING, "RedisCache containsKey operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public Map getAll() throws CacheException { + try { + return hashOperations.entries(name); + } catch (Exception e) { + logger.log(Level.WARNING, "RedisCache getAll operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public void putAll(Map items) throws CacheException { + try { + hashOperations.putAll(name, items); + } catch (Exception e) { + logger.log(Level.WARNING, "RedisCache putAll operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public boolean remove(K key) throws CacheException { + try { + return hashOperations.delete(name, key) == 1; + } catch (Exception e) { + logger.log(Level.WARNING, "RedisCache remove operation error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + @Override + public Transaction getTransaction() { + return transaction; + } +} diff --git a/src/com/futurewei/alcor/controller/cache/config/RedisConfiguration.java b/src/com/futurewei/alcor/controller/db/redis/RedisConfiguration.java similarity index 96% rename from src/com/futurewei/alcor/controller/cache/config/RedisConfiguration.java rename to src/com/futurewei/alcor/controller/db/redis/RedisConfiguration.java index 9109f0d7..466e4f5e 100644 --- a/src/com/futurewei/alcor/controller/cache/config/RedisConfiguration.java +++ b/src/com/futurewei/alcor/controller/db/redis/RedisConfiguration.java @@ -14,7 +14,7 @@ limitations under the License. */ -package com.futurewei.alcor.controller.cache.config; +package com.futurewei.alcor.controller.db.redis; import com.futurewei.alcor.controller.cache.message.ICachePublisher; import com.futurewei.alcor.controller.cache.message.RedisListener; @@ -37,8 +37,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration -@ComponentScan("com.futurewei.alcor.controller.cache") -@EntityScan("com.futurewei.alcor.controller.cache") +@ComponentScan("com.futurewei.alcor.controller.db") +@EntityScan("com.futurewei.alcor.controller.db") public class RedisConfiguration { @Value("${spring.redis.host}") diff --git a/src/com/futurewei/alcor/controller/db/redis/RedisTransaction.java b/src/com/futurewei/alcor/controller/db/redis/RedisTransaction.java new file mode 100644 index 00000000..4b5b08f7 --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/redis/RedisTransaction.java @@ -0,0 +1,68 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.redis; + +import com.futurewei.alcor.controller.db.Transaction; +import com.futurewei.alcor.controller.exception.CacheException; +import com.futurewei.alcor.controller.logging.Logger; +import com.futurewei.alcor.controller.logging.LoggerFactory; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.logging.Level; + + +public class RedisTransaction implements Transaction { + private static final Logger logger = LoggerFactory.getLogger(); + + private RedisTemplate redisTemplate; + + public RedisTransaction(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + public void start() throws CacheException { + redisTemplate.setEnableTransactionSupport(true); + try { + redisTemplate.multi(); + } catch (Exception e) { + logger.log(Level.WARNING, "RedisTransaction start error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + public void commit() throws CacheException { + try { + redisTemplate.exec(); + } catch (Exception e) { + logger.log(Level.WARNING, "RedisTransaction commit error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + public void rollback() throws CacheException { + try { + redisTemplate.discard(); + } catch (Exception e) { + logger.log(Level.WARNING, "RedisTransaction rollback error:" + e.getMessage()); + throw new CacheException(e.getMessage()); + } + } + + public void close() { + //Do nothing + } +} diff --git a/src/com/futurewei/alcor/controller/db/repo/ICacheRepository.java b/src/com/futurewei/alcor/controller/db/repo/ICacheRepository.java new file mode 100644 index 00000000..2df78e8a --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/repo/ICacheRepository.java @@ -0,0 +1,32 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.repo; + +import com.futurewei.alcor.controller.exception.CacheException; + +import java.util.Map; + +public interface ICacheRepository { + + T findItem(String id) throws CacheException; + + Map findAllItems() throws CacheException; + + void addItem(T newItem) throws CacheException; + + void deleteItem(String id) throws CacheException; +} diff --git a/src/com/futurewei/alcor/controller/cache/repo/PortRedisRepository.java b/src/com/futurewei/alcor/controller/db/repo/PortRedisRepository.java similarity index 97% rename from src/com/futurewei/alcor/controller/cache/repo/PortRedisRepository.java rename to src/com/futurewei/alcor/controller/db/repo/PortRedisRepository.java index 2f266eb9..010f2df2 100644 --- a/src/com/futurewei/alcor/controller/cache/repo/PortRedisRepository.java +++ b/src/com/futurewei/alcor/controller/db/repo/PortRedisRepository.java @@ -14,7 +14,7 @@ limitations under the License. */ -package com.futurewei.alcor.controller.cache.repo; +package com.futurewei.alcor.controller.db.repo; import com.futurewei.alcor.controller.logging.Logger; import com.futurewei.alcor.controller.logging.LoggerFactory; diff --git a/src/com/futurewei/alcor/controller/db/repo/PortRepository.java b/src/com/futurewei/alcor/controller/db/repo/PortRepository.java new file mode 100644 index 00000000..6c8bae09 --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/repo/PortRepository.java @@ -0,0 +1,70 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.repo; + +import com.futurewei.alcor.controller.db.CacheFactory; +import com.futurewei.alcor.controller.db.ICache; +import com.futurewei.alcor.controller.exception.CacheException; +import com.futurewei.alcor.controller.logging.Logger; +import com.futurewei.alcor.controller.logging.LoggerFactory; +import com.futurewei.alcor.controller.model.PortState; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Repository; + +import javax.annotation.PostConstruct; +import java.util.Map; +import java.util.logging.Level; + +@Repository +@ConditionalOnBean(CacheFactory.class) +public class PortRepository implements ICacheRepository { + private static final Logger logger = LoggerFactory.getLogger(); + + private ICache cache; + + @Autowired + public PortRepository(CacheFactory cacheFactory) { + cache = cacheFactory.getCache(PortState.class); + } + + @PostConstruct + private void init() { + logger.log(Level.INFO, "PortRepository init completed"); + } + + @Override + public PortState findItem(String id) throws CacheException { + return cache.get(id); + } + + @Override + public Map findAllItems() throws CacheException { + return cache.getAll(); + } + + @Override + public void addItem(PortState newItem) throws CacheException { + logger.log(Level.INFO, "Port Id:" + newItem.getId()); + cache.put(newItem.getId(), newItem); + } + + @Override + public void deleteItem(String id) throws CacheException { + cache.remove(id); + } +} diff --git a/src/com/futurewei/alcor/controller/cache/repo/SubnetRedisRepository.java b/src/com/futurewei/alcor/controller/db/repo/SubnetRedisRepository.java similarity index 97% rename from src/com/futurewei/alcor/controller/cache/repo/SubnetRedisRepository.java rename to src/com/futurewei/alcor/controller/db/repo/SubnetRedisRepository.java index 9dac2f03..118b4d57 100644 --- a/src/com/futurewei/alcor/controller/cache/repo/SubnetRedisRepository.java +++ b/src/com/futurewei/alcor/controller/db/repo/SubnetRedisRepository.java @@ -14,7 +14,7 @@ limitations under the License. */ -package com.futurewei.alcor.controller.cache.repo; +package com.futurewei.alcor.controller.db.repo; import com.futurewei.alcor.controller.logging.Logger; import com.futurewei.alcor.controller.logging.LoggerFactory; diff --git a/src/com/futurewei/alcor/controller/db/repo/SubnetRepository.java b/src/com/futurewei/alcor/controller/db/repo/SubnetRepository.java new file mode 100644 index 00000000..faf45850 --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/repo/SubnetRepository.java @@ -0,0 +1,71 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.repo; + +import com.futurewei.alcor.controller.db.CacheFactory; +import com.futurewei.alcor.controller.db.ICache; +import com.futurewei.alcor.controller.exception.CacheException; +import com.futurewei.alcor.controller.logging.Logger; +import com.futurewei.alcor.controller.logging.LoggerFactory; +import com.futurewei.alcor.controller.model.SubnetState; +import com.futurewei.alcor.controller.schema.Subnet; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Repository; + +import javax.annotation.PostConstruct; +import java.util.Map; +import java.util.logging.Level; + +@Repository +@ConditionalOnBean(CacheFactory.class) +public class SubnetRepository implements ICacheRepository { + private static final Logger logger = LoggerFactory.getLogger(); + + private ICache cache; + + @Autowired + public SubnetRepository(CacheFactory cacheFactory) { + cache = cacheFactory.getCache(Subnet.class); + } + + @PostConstruct + private void init() { + logger.log(Level.INFO, "SubnetRepository init completed"); + } + + @Override + public SubnetState findItem(String id) throws CacheException { + return cache.get(id); + } + + @Override + public Map findAllItems() throws CacheException { + return cache.getAll(); + } + + @Override + public void addItem(SubnetState newItem) throws CacheException{ + logger.log(Level.INFO, "Subnet Id:" + newItem.getId()); + cache.put(newItem.getId(), newItem); + } + + @Override + public void deleteItem(String id) throws CacheException { + cache.remove(id); + } +} diff --git a/src/com/futurewei/alcor/controller/cache/repo/VpcRedisRepository.java b/src/com/futurewei/alcor/controller/db/repo/VpcRedisRepository.java similarity index 97% rename from src/com/futurewei/alcor/controller/cache/repo/VpcRedisRepository.java rename to src/com/futurewei/alcor/controller/db/repo/VpcRedisRepository.java index 7ed4b017..65c10e95 100644 --- a/src/com/futurewei/alcor/controller/cache/repo/VpcRedisRepository.java +++ b/src/com/futurewei/alcor/controller/db/repo/VpcRedisRepository.java @@ -14,7 +14,7 @@ limitations under the License. */ -package com.futurewei.alcor.controller.cache.repo; +package com.futurewei.alcor.controller.db.repo; import com.futurewei.alcor.controller.logging.Logger; import com.futurewei.alcor.controller.logging.LoggerFactory; diff --git a/src/com/futurewei/alcor/controller/db/repo/VpcRepository.java b/src/com/futurewei/alcor/controller/db/repo/VpcRepository.java new file mode 100644 index 00000000..f23a115d --- /dev/null +++ b/src/com/futurewei/alcor/controller/db/repo/VpcRepository.java @@ -0,0 +1,74 @@ +/* +Copyright 2019 The Alcor Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.futurewei.alcor.controller.db.repo; + +import com.futurewei.alcor.controller.db.CacheFactory; +import com.futurewei.alcor.controller.db.ICache; +import com.futurewei.alcor.controller.exception.CacheException; +import com.futurewei.alcor.controller.logging.Logger; +import com.futurewei.alcor.controller.logging.LoggerFactory; +import com.futurewei.alcor.controller.model.VpcState; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Repository; +import javax.annotation.PostConstruct; +import java.util.Map; +import java.util.logging.Level; + +@Repository +@ConditionalOnBean(CacheFactory.class) +public class VpcRepository implements ICacheRepository { + private static final Logger logger = LoggerFactory.getLogger(); + + public ICache getCache() { + return cache; + } + + private ICache cache; + + @Autowired + public VpcRepository(CacheFactory cacheFactory) { + cache = cacheFactory.getCache(VpcState.class); + } + + @PostConstruct + private void init() { + logger.log(Level.INFO, "VpcRepository init completed"); + } + + @Override + public VpcState findItem(String id) throws CacheException { + return cache.get(id); + } + + @Override + public Map findAllItems() throws CacheException { + return cache.getAll(); + } + + @Override + public void addItem(VpcState vpcState) throws CacheException { + logger.log(Level.INFO, "Add vpc, Vpc Id:" + vpcState.getId()); + cache.put(vpcState.getId(), vpcState); + } + + @Override + public void deleteItem(String id) throws CacheException { + logger.log(Level.INFO, "Delete vpc, Vpc Id:" + id); + cache.remove(id); + } +} diff --git a/src/com/futurewei/alcor/controller/exception/CacheException.java b/src/com/futurewei/alcor/controller/exception/CacheException.java new file mode 100644 index 00000000..cd9549b2 --- /dev/null +++ b/src/com/futurewei/alcor/controller/exception/CacheException.java @@ -0,0 +1,20 @@ +package com.futurewei.alcor.controller.exception; + +public class CacheException extends Exception { + private static final long serialVersionUID = 1L; + + public CacheException() { + } + + public CacheException(String message) { + super(message); + } + + public CacheException(String message, Throwable cause) { + super(message, cause); + } + + public CacheException(Throwable cause) { + super(cause); + } +} diff --git a/src/com/futurewei/alcor/controller/model/CustomerResource.java b/src/com/futurewei/alcor/controller/model/CustomerResource.java index 239d8cfb..ae176ce8 100644 --- a/src/com/futurewei/alcor/controller/model/CustomerResource.java +++ b/src/com/futurewei/alcor/controller/model/CustomerResource.java @@ -19,8 +19,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; +import java.io.Serializable; + @Data -public class CustomerResource { +public class CustomerResource implements Serializable { @JsonProperty("project_id") private String projectId; diff --git a/src/com/futurewei/alcor/controller/web/DebugController.java b/src/com/futurewei/alcor/controller/web/DebugController.java index ef358384..b8f57998 100644 --- a/src/com/futurewei/alcor/controller/web/DebugController.java +++ b/src/com/futurewei/alcor/controller/web/DebugController.java @@ -16,8 +16,8 @@ package com.futurewei.alcor.controller.web; -import com.futurewei.alcor.controller.cache.repo.SubnetRedisRepository; -import com.futurewei.alcor.controller.cache.repo.VpcRedisRepository; +import com.futurewei.alcor.controller.db.repo.SubnetRedisRepository; +import com.futurewei.alcor.controller.db.repo.VpcRedisRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; diff --git a/src/com/futurewei/alcor/controller/web/DebugVpcController.java b/src/com/futurewei/alcor/controller/web/DebugVpcController.java new file mode 100644 index 00000000..c60dec7d --- /dev/null +++ b/src/com/futurewei/alcor/controller/web/DebugVpcController.java @@ -0,0 +1,164 @@ +package com.futurewei.alcor.controller.web; + +import com.futurewei.alcor.controller.db.repo.VpcRepository; +import com.futurewei.alcor.controller.exception.CacheException; +import com.futurewei.alcor.controller.db.Transaction; +import com.futurewei.alcor.controller.exception.*; +import com.futurewei.alcor.controller.model.ResponseId; +import com.futurewei.alcor.controller.model.VpcState; +import com.futurewei.alcor.controller.model.VpcStateJson; +import com.futurewei.alcor.controller.web.util.RestPreconditions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +import static org.springframework.web.bind.annotation.RequestMethod.*; +import static org.springframework.web.bind.annotation.RequestMethod.DELETE; + +@RestController +public class DebugVpcController { + @Autowired(required = false) + private VpcRepository vpcRepository; + + @RequestMapping( + method = GET, + value = {"/debug/project/{projectid}/vpcs/{vpcid}"}) + public VpcStateJson getVpcStateByVpcId(@PathVariable String projectid, @PathVariable String vpcid) throws Exception { + + VpcState vpcState = null; + + try { + RestPreconditions.verifyParameterNotNullorEmpty(projectid); + RestPreconditions.verifyParameterNotNullorEmpty(vpcid); + RestPreconditions.verifyResourceFound(projectid); + + vpcState = this.vpcRepository.findItem(vpcid); + } catch (ParameterNullOrEmptyException e) { + //TODO: REST error code + throw new Exception(e); + } + + if (vpcState == null) { + //TODO: REST error code + return new VpcStateJson(); + } + + return new VpcStateJson(vpcState); + } + + @RequestMapping( + method = GET, + value = "/debug/project/all/vpcs") + public Map getVpcCountAndAllVpcStates() throws CacheException { + Map result = new HashMap(); + Map dataItems = vpcRepository.findAllItems(); + result.put("Count", dataItems.size()); + result.put("Vpcs", dataItems); + + return result; + } + + @RequestMapping( + method = GET, + value = "/debug/project/all/vpccount") + public Map getVpcCount() throws CacheException { + Map result = new HashMap(); + Map dataItems = vpcRepository.findAllItems(); + result.put("Count", dataItems.size()); + + return result; + } + + @RequestMapping( + method = POST, + value = {"/debug/project/{projectid}/vpcs"}) + @ResponseStatus(HttpStatus.CREATED) + public VpcStateJson createVpcState(@PathVariable String projectid, @RequestBody VpcStateJson resource) throws Exception { + VpcState vpcState = null; + + try { + RestPreconditions.verifyParameterNotNullorEmpty(projectid); + + VpcState inVpcState = resource.getVpc(); + RestPreconditions.verifyResourceNotNull(inVpcState); + RestPreconditions.populateResourceProjectId(inVpcState, projectid); + + Transaction transaction = this.vpcRepository.getCache().getTransaction(); + transaction.start(); + + this.vpcRepository.addItem(inVpcState); + vpcState = this.vpcRepository.findItem(inVpcState.getId()); + + transaction.commit(); + + if (vpcState == null) { + throw new ResourcePersistenceException(); + } + } catch (ParameterNullOrEmptyException e) { + throw new Exception(e); + } catch (ResourceNullException e) { + throw new Exception(e); + } + + return new VpcStateJson(vpcState); + } + + @RequestMapping( + method = PUT, + value = {"/debug/project/{projectid}/vpcs/{vpcid}"}) + public VpcStateJson updateVpcStateByVpcId(@PathVariable String projectid, @PathVariable String vpcid, @RequestBody VpcStateJson resource) throws Exception { + + VpcState vpcState = null; + + try { + RestPreconditions.verifyParameterNotNullorEmpty(projectid); + RestPreconditions.verifyParameterNotNullorEmpty(vpcid); + + VpcState inVpcState = resource.getVpc(); + RestPreconditions.verifyResourceNotNull(inVpcState); + RestPreconditions.populateResourceProjectId(inVpcState, projectid); + RestPreconditions.populateResourceVpcId(inVpcState, vpcid); + + vpcState = this.vpcRepository.findItem(vpcid); + if (vpcState == null) { + throw new ResourceNotFoundException("Vpc not found : " + vpcid); + } + + this.vpcRepository.addItem(inVpcState); + + vpcState = this.vpcRepository.findItem(vpcid); + + } catch (ParameterNullOrEmptyException e) { + throw new Exception(e); + } + + return new VpcStateJson(vpcState); + } + + @RequestMapping( + method = DELETE, + value = {"/debug/project/{projectid}/vpcs/{vpcid}"}) + public ResponseId deleteVpcStateByVpcId(@PathVariable String projectid, @PathVariable String vpcid) throws Exception { + VpcState vpcState = null; + + try { + RestPreconditions.verifyParameterNotNullorEmpty(projectid); + RestPreconditions.verifyParameterNotNullorEmpty(vpcid); + RestPreconditions.verifyResourceFound(projectid); + + vpcState = this.vpcRepository.findItem(vpcid); + if (vpcState == null) { + return new ResponseId(); + } + + vpcRepository.deleteItem(vpcid); + } catch (ParameterNullOrEmptyException e) { + throw new Exception(e); + } + + return new ResponseId(vpcid); + } +} diff --git a/src/com/futurewei/alcor/controller/web/PortController.java b/src/com/futurewei/alcor/controller/web/PortController.java index e6fe3ed8..b4a667ee 100644 --- a/src/com/futurewei/alcor/controller/web/PortController.java +++ b/src/com/futurewei/alcor/controller/web/PortController.java @@ -17,9 +17,9 @@ package com.futurewei.alcor.controller.web; import com.futurewei.alcor.controller.app.onebox.*; -import com.futurewei.alcor.controller.cache.repo.PortRedisRepository; -import com.futurewei.alcor.controller.cache.repo.SubnetRedisRepository; -import com.futurewei.alcor.controller.cache.repo.VpcRedisRepository; +import com.futurewei.alcor.controller.db.repo.PortRedisRepository; +import com.futurewei.alcor.controller.db.repo.SubnetRedisRepository; +import com.futurewei.alcor.controller.db.repo.VpcRedisRepository; import com.futurewei.alcor.controller.exception.ParameterNullOrEmptyException; import com.futurewei.alcor.controller.exception.ParameterUnexpectedValueException; import com.futurewei.alcor.controller.exception.ResourceNotFoundException; diff --git a/src/com/futurewei/alcor/controller/web/SubnetController.java b/src/com/futurewei/alcor/controller/web/SubnetController.java index 41d34f90..808337ff 100644 --- a/src/com/futurewei/alcor/controller/web/SubnetController.java +++ b/src/com/futurewei/alcor/controller/web/SubnetController.java @@ -16,8 +16,8 @@ package com.futurewei.alcor.controller.web; -import com.futurewei.alcor.controller.cache.repo.SubnetRedisRepository; -import com.futurewei.alcor.controller.cache.repo.VpcRedisRepository; +import com.futurewei.alcor.controller.db.repo.SubnetRedisRepository; +import com.futurewei.alcor.controller.db.repo.VpcRedisRepository; import com.futurewei.alcor.controller.exception.*; import com.futurewei.alcor.controller.model.ResponseId; import com.futurewei.alcor.controller.model.SubnetState; diff --git a/src/com/futurewei/alcor/controller/web/VpcController.java b/src/com/futurewei/alcor/controller/web/VpcController.java index 6d0bf738..6b6152f1 100644 --- a/src/com/futurewei/alcor/controller/web/VpcController.java +++ b/src/com/futurewei/alcor/controller/web/VpcController.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.stream.Collectors; -import com.futurewei.alcor.controller.cache.repo.VpcRedisRepository; +import com.futurewei.alcor.controller.db.repo.VpcRedisRepository; import com.futurewei.alcor.controller.exception.ParameterNullOrEmptyException; import com.futurewei.alcor.controller.exception.ResourceNotFoundException; import com.futurewei.alcor.controller.exception.ResourceNullException; diff --git a/src/resources/application.properties b/src/resources/application.properties index 581f6551..9ee727e7 100644 --- a/src/resources/application.properties +++ b/src/resources/application.properties @@ -9,3 +9,10 @@ logging.level.root=info logging.level.org.springframework.web=info logging.file.path=. logging.type=file +#Ignite configuration +#ignite.host=localhost +#ignite.port=10800 +#ignite.key-store-path=F:\\work\\alcor\\git\\chenpp\\alcor\\src\\resources\\keystore.jks +#ignite.key-store-password=123456 +#ignite.trust-store-path=F:\\work\\alcor\\git\\chenpp\\alcor\\src\\resources\\truststore.jks +#ignite.trust-store-password=123456 \ No newline at end of file diff --git a/src/resources/example_keystore.jks b/src/resources/example_keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..9d4476766822e88b2d917137a701a0c48f67dacf GIT binary patch literal 347 zcmXqLVhm?uWHxAG6ky}jYV&CO&dbQoxS)xVk)`pULE~?O#vjPyjjvc5pBpqjF=%|q z#tl`@!^OzDpvs^ES%7IlCQG_Os(~gO7fcn<5@{BZcaiC5j>%`5S7$Ub?7y7L^U~A# z6%#YV;Q$tkgEN!)>R%t3&>R2F-OX;v)Vt@>ekv*Mdsn1#fZZ?Ph$<|I5xK5iDa(wl)YvA3 zqNHr4v4-r7U6#5iOW!%2?>*oCf$tCR56^SX^M20fec$suhiivx0002QDd5lIBluq< z2VD*#_>ldt_(yVR;%ae;006)RKvN+5Xg(;93KR$dDuV=pKrR4;0$E(ou{Qn6rQ{rp zflVbWpVzIQb9OIYjIB)M>i~{6Sjz2HZ>Y^>ZPbO@9$E4KeuqW)u5d82&8W38Gs@^c=kB5aj{Jd&oF=zaPCDf19eV+@~ zW&XS9&4t-pz7QfUK$2|itF;+Oy&Fx*e2rfrA5#hQR)C(-K&&7yAqpcNduB`ya#NfV zu|Y}lc#PD-4fLV*0Fj8h5QOsxZ99I;_v{F!m0ek&{0z8nvN{3+4mk-F@FW;_u!gmC3KSqDm4v-J9cl>Ij)y!Tj`evKLL{+F=x| zz>Gh~33s)5*;4kIQ~1%m#-g#%nLyXfd5l5A2F>u~a27Z$;I#056@NwTNfSP0S$4QZ z9Z8&}Kd%Xe?KZ7 zUMbu$>*?4wY-&#)n=7WM7%jG4V4RpVG7eL3s(JgBG$p9`=P`i`f=KJrD}FD&T~kp! zhGb^i8Z;3ZH>S7dMjWTR@r8M^rDNpA{W4#LRk~~ajo4b3=Eu4{t9sckezy&%@fSN0 zr`q;0)hXN`(YdY6$$WShyre<;(X7}X%sSKnwS8+K-16C0j_NF%%P2T<^J1Ue(gGoBei4Ly{9wBAkbVPe5Yai(kAAdGLL`e2* zrC684zt|rjdg1=`Wto6|M8;j4FrYS~pX}F_fIA10Wq2MZM*dxxg2yTPiJBSOg%tW2 z0^Th4xnz{bJ$KY?S)IAlQI&Ih-G$M;R5Y@o(0aP1t8b^^;fm8NFV%arW@&p-$^4Tk(Xg|>JbR=f z29s2H{e@-+ruov7tJcuK#*_Ic9>6i}QMXIJ{2(5l;D01mRtjU=|0a%-_=vn1#a2uQ zq}Y}>-Dopl4$DgudVV;VXC#NWE<0^E%2f&cB#fqBcROi|YtA+r&J|RE-k;_d@ z2dxhPfIZO^@Od-^WLyXa0YM-LZhWBx%?pJqQ?02xyg(p=W0+nV2s9iDc7;HNKxPga z0vz|`0GJTBuYXW*P*}jf4EO(-{|b17K!Fkesu4c{Kc_oK4HkkD0{z2?M6~2_UQIMw zOG6Kh(b3V-^WZ>@U*P}wbqY}S*Y9$&089b$b3y{h1EK(dfH=j^G97Q8Z{2hSPtw)Z znP0|iKMhEQl)Q_x2sq00?!5QTSc-S=g{O_X?N#o?T`Bfn%>*`Us=0DWT#hmAwa8O< z7aPBJQ~r|S)`zJ^f~AvKr%E(mo!j7ijRv=t&hLJ~p8Ac<2*b-AE%1B|H&~EzFD5cc zixm9178{-#V&pJUl&e%D6X8(Klx$m&#tB+V>L>GCh;^jnH8E0clep@*^&saNlRzc2 z7zfYAk`vvEeC@rS!b<9ssZJiMgWA<1`Ow3~1?hyUK9BEqHK7uv`dw>f z`4VFz;d6Y@xwSLcc{))a^<~UMt8M#%u=jGq?(FzQ5(o?g0E=YMQfL%sZJhKGfgBsG zCe$siBOSHV)~R8|acF_9p8a2k$hjHL5P^VT)kgO?^Ed?KPQ)2%+hU0L2N#+uhF!1z z{-~X7w|~Jks*D;MW?iR+FUtyb&P%e2WL*#HpPy=++1`1l32%{^_BM80GGWlA5Q;fY zE_<5ov9Wrw))aP6V@lq}m7=Le9)?0?U?E?}k2wb`{H)McPK6m{NP zKUgeVt>*aAkm%(5LlI}~Aztw-QaiX-o+AR6t8$WeKOIhE2~)$4u`F=I?Ezhp3DYL@ zXv&%&YiK~a(0WOayHmIV`P9fVTZteC{&S&t$TatTd)>)uZM;EW+7F0+oX!&~mP{qh u=f>O$*=^IaYbw*ia9`|kT1Y9s`PWU;2|(A=4%^!4>R^0LYa+hPF6KYXyUn5i literal 0 HcmV?d00001 diff --git a/src/resources/truststore.jks b/src/resources/truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..adef05e5c6702a285b5e24bd0ab7fe27940916a4 GIT binary patch literal 930 zcmezO_TO6u1_mY|W(3oG$*DypnQ58Hi6yDosg*$Cf;Y>)pJiZ;&@(l#WME*9HfUlF zH)vwAU%<@7$i&2Ad-wTL170>xtu~Lg@4SqR+^h@+F^1d*oNUaYENsF|&VGgh27Dk6 zhcJ6mYGzhuUOG&K9U%hMz$MI-Q4Z714d(CzO$X{`7G_J%NX;uKFpv}HH8L zH#If2hyrpAk+?Lry@^o?*}IIa49rc8{0s(7j9g4jjEoG88t)WO9NqJ&C6xL8B7ObM zpYM3xz9OHq^h~2`y3pqMlQYlQ%k%!;8|@kCmCxS!L;mUSP4}#)KG?VZrL^+ehcPd> zw#~3^e%qp&VDstxgI&pP0a7QmYx%ZCTz$65klom{A|)%@a@Xc^o3s=AIp-NhaAay- zG_UM3F3x(l)w*m#j-B7V#j`XwDVF=K+AMeExq_{ro1A42zpK=VNkK;D@<;C5Zfty? z8TiOCL({q5FZ#t&mD3u0$1g^UYUf8ikX-h85kEU z8ps>S0;5fqk420{GL5AbpEo&kr)Hshe>Q*#67cDYwxD9yb5?7^-_ z-@czQ;@q$JFy7w(rQ_N~^4uEJ144cq9dBr`Xjt{2xalcd^Zf+%S|`D`E8-t0Jq@)@ zVURQb^J{9UfV&Cn$5S7KPgxmVs}7I1%#xa>w@F+mr?zMIwenzJmYC+(^51O_aq$SG zZJ6Hk