diff --git a/dubbo-plugin/dubbo-security/pom.xml b/dubbo-plugin/dubbo-security/pom.xml index bcc16b68ea..a76f713264 100644 --- a/dubbo-plugin/dubbo-security/pom.xml +++ b/dubbo-plugin/dubbo-security/pom.xml @@ -35,7 +35,7 @@ org.apache.dubbo - dubbo-rpc-api + dubbo-config-api ${project.version} @@ -49,20 +49,6 @@ dubbo-common ${project.version} - - - - io.grpc - grpc-protobuf - - - io.grpc - grpc-stub - - - io.grpc - grpc-netty-shaded - com.google.protobuf @@ -86,13 +72,14 @@ bcprov-ext-jdk15on - + org.apache.dubbo - dubbo-config-api + dubbo-remoting-netty4 ${project.version} test + @@ -103,19 +90,24 @@ ${maven_protobuf_plugin_version} com.google.protobuf:protoc:${protobuf-protoc_version}:exe:${os.detected.classifier} - grpc-java - io.grpc:protoc-gen-grpc-java:${grpc_version}:exe:${os.detected.classifier} + + + dubbo + org.apache.dubbo + dubbo-compiler + ${project.version} + org.apache.dubbo.gen.tri.Dubbo3TripleGenerator + + compile - compile-custom - org.apache.maven.plugins maven-javadoc-plugin diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertScopeModelInitializer.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertScopeModelInitializer.java index ccf9be4bd8..1cce4b6a98 100644 --- a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertScopeModelInitializer.java +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertScopeModelInitializer.java @@ -26,7 +26,8 @@ import org.apache.dubbo.rpc.model.ScopeModelInitializer; public class CertScopeModelInitializer implements ScopeModelInitializer { public static boolean isSupported() { try { - ClassUtils.forName("io.grpc.Channel"); + + ClassUtils.forName("org.apache.dubbo.config.ReferenceConfig"); ClassUtils.forName("org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder"); return true; } catch (Throwable t) { diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertManager.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertManager.java index bddef4a094..16a8007802 100644 --- a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertManager.java +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertManager.java @@ -18,34 +18,38 @@ package org.apache.dubbo.security.cert; import org.apache.dubbo.auth.v1alpha1.DubboCertificateRequest; import org.apache.dubbo.auth.v1alpha1.DubboCertificateResponse; -import org.apache.dubbo.auth.v1alpha1.DubboCertificateServiceGrpc; +import org.apache.dubbo.auth.v1alpha1.DubboCertificateService; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.constants.LoggerCodeConstants; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; import org.apache.dubbo.common.utils.IOUtils; import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.config.ReferenceConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.SslConfig; +import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.model.FrameworkModel; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.StringWriter; +import java.nio.file.Files; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; +import java.security.cert.CertificateFactory; import java.security.spec.ECGenParameterSpec; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; -import io.grpc.Channel; -import io.grpc.Metadata; -import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts; -import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder; -import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import org.bouncycastle.operator.ContentSigner; @@ -55,7 +59,6 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; import org.bouncycastle.util.io.pem.PemObject; -import static io.grpc.stub.MetadataUtils.newAttachHeadersInterceptor; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_SSL_CERT_GENERATE_FAILED; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_SSL_CONNECT_INSECURE; import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR; @@ -66,10 +69,13 @@ public class DubboCertManager { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(DubboCertManager.class); private final FrameworkModel frameworkModel; + + private final AtomicReference dubboBootstrapRef = new AtomicReference<>(); /** - * gRPC channel to Dubbo Cert Authority server + * Triple CertificateService reference */ - protected volatile Channel channel; + private final AtomicReference> referenceRef = new AtomicReference<>(); + /** * Cert pair for current Dubbo instance */ @@ -83,12 +89,82 @@ public class DubboCertManager { */ protected volatile ScheduledFuture refreshFuture; + public DubboBootstrap getDubboBootstrap() { + return dubboBootstrapRef.get(); + } + + public void setDubboBootstrap(DubboBootstrap bootstrap) { + dubboBootstrapRef.set(bootstrap); + } + + public ReferenceConfig getReference() { + return referenceRef.get(); + } + + public void setReference(ReferenceConfig ref) { + referenceRef.set(ref); + } + public DubboCertManager(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; } + /** + * Generate key pair with RSA + * + * @return key pair + */ + protected static KeyPair signWithRsa() { + KeyPair keyPair = null; + try { + KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA"); + kpGenerator.initialize(4096); + java.security.KeyPair keypair = kpGenerator.generateKeyPair(); + PublicKey publicKey = keypair.getPublic(); + PrivateKey privateKey = keypair.getPrivate(); + ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").build(keypair.getPrivate()); + keyPair = new KeyPair(publicKey, privateKey, signer); + } catch (NoSuchAlgorithmException | OperatorCreationException e) { + logger.error( + CONFIG_SSL_CERT_GENERATE_FAILED, + "", + "", + "Generate Key with SHA256WithRSA algorithm failed. " + "Please check if your system support.", + e); + } + return keyPair; + } + + /** + * Generate key pair with ECDSA + * + * @return key pair + */ + protected static KeyPair signWithEcdsa() { + KeyPair keyPair = null; + try { + ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1"); + KeyPairGenerator g = KeyPairGenerator.getInstance("EC"); + g.initialize(ecSpec, new SecureRandom()); + java.security.KeyPair keypair = g.generateKeyPair(); + PublicKey publicKey = keypair.getPublic(); + PrivateKey privateKey = keypair.getPrivate(); + ContentSigner signer = new JcaContentSignerBuilder("SHA256withECDSA").build(privateKey); + keyPair = new KeyPair(publicKey, privateKey, signer); + } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | OperatorCreationException e) { + logger.error( + CONFIG_SSL_CERT_GENERATE_FAILED, + "", + "", + "Generate Key with secp256r1 algorithm failed. Please check if your system support. " + + "Will attempt to generate with RSA2048.", + e); + } + return keyPair; + } + public synchronized void connect(CertConfig certConfig) { - if (channel != null) { + if (getReference() != null) { logger.error(INTERNAL_ERROR, "", "", "Dubbo Cert Authority server is already connected."); return; } @@ -140,25 +216,35 @@ public class DubboCertManager { String remoteAddress = certConfig.getRemoteAddress(); logger.info( "Try to connect to Dubbo Cert Authority server: " + remoteAddress + ", caCertPath: " + remoteAddress); + ReferenceConfig ref = new ReferenceConfig<>(); + ref.setInterface(DubboCertificateService.class); + ref.setProxy(CommonConstants.NATIVE_STUB); + ref.setUrl("tri://" + remoteAddress); + ref.setTimeout(3000); + setReference(ref); + DubboBootstrap dubboBootstrap = + DubboBootstrap.newInstance().registry(new RegistryConfig("N/A")).reference(getReference()); + setDubboBootstrap(dubboBootstrap); try { + if (StringUtils.isNotEmpty(caCertPath)) { - channel = NettyChannelBuilder.forTarget(remoteAddress) - .sslContext(GrpcSslContexts.forClient() - .trustManager(new File(caCertPath)) - .build()) - .build(); + File caFile = new File(caCertPath); + // Check if caCert is valid + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + cf.generateCertificate(Files.newInputStream(caFile.toPath())); + + SslConfig sslConfig = new SslConfig(); + sslConfig.setCaCertPath(caCertPath); + dubboBootstrap.ssl(sslConfig); + } else { logger.warn( CONFIG_SSL_CONNECT_INSECURE, "", "", - "No caCertPath is provided, will use insecure connection."); - channel = NettyChannelBuilder.forTarget(remoteAddress) - .sslContext(GrpcSslContexts.forClient() - .trustManager(InsecureTrustManagerFactory.INSTANCE) - .build()) - .build(); + "No caCertPath is provided, will use insecure " + "connection."); } + } catch (Exception e) { logger.error(LoggerCodeConstants.CONFIG_SSL_PATH_LOAD_FAILED, "", "", "Failed to load SSL cert file.", e); throw new RuntimeException(e); @@ -170,13 +256,13 @@ public class DubboCertManager { refreshFuture.cancel(true); refreshFuture = null; } - if (channel != null) { - channel = null; + if (getReference() != null) { + setReference(null); } } public boolean isConnected() { - return certConfig != null && channel != null && certPair != null; + return certConfig != null && getReference() != null && certPair != null; } protected CertPair generateCert() { @@ -195,7 +281,7 @@ public class DubboCertManager { CONFIG_SSL_CERT_GENERATE_FAILED, "", "", - "Generate Cert from Dubbo Certificate Authority failed."); + "Generate Cert from Dubbo Certificate " + "Authority failed."); } } catch (Exception e) { logger.error(REGISTRY_FAILED_GENERATE_CERT_ISTIO, "", "", "Generate Cert from Istio failed.", e); @@ -223,17 +309,17 @@ public class DubboCertManager { CONFIG_SSL_CERT_GENERATE_FAILED, "", "", - "Generate Key failed. Please check if your system support."); + "Generate Key failed. Please check if your system " + "support."); return null; } String csr = generateCsr(keyPair); - DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub stub = - DubboCertificateServiceGrpc.newBlockingStub(channel); - stub = setHeaderIfNeed(stub); + getDubboBootstrap().start(); + DubboCertificateService dubboCertificateService = getReference().get(); + setHeaderIfNeed(); String privateKeyPem = generatePrivatePemKey(keyPair); - DubboCertificateResponse certificateResponse = stub.createCertificate(generateRequest(csr)); + DubboCertificateResponse certificateResponse = dubboCertificateService.createCertificate(generateRequest(csr)); if (certificateResponse == null || !certificateResponse.getSuccess()) { logger.error( @@ -254,85 +340,28 @@ public class DubboCertManager { certificateResponse.getExpireTime()); } - private DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub setHeaderIfNeed( - DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub stub) throws IOException { + private void setHeaderIfNeed() throws IOException { String oidcTokenPath = certConfig.getOidcTokenPath(); if (StringUtils.isNotEmpty(oidcTokenPath)) { - Metadata header = new Metadata(); - Metadata.Key key = Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER); - header.put( - key, - "Bearer " - + IOUtils.read(new FileReader(oidcTokenPath)) - .replace("\n", "") - .replace("\t", "") - .replace("\r", "") - .trim()); - stub = stub.withInterceptors(newAttachHeadersInterceptor(header)); + RpcContext.getClientAttachment() + .setAttachment( + "authorization", + "Bearer " + + IOUtils.read(new FileReader(oidcTokenPath)) + .replace("\n", "") + .replace("\t", "") + .replace("\r", "") + .trim()); logger.info("Use oidc token from " + oidcTokenPath + " to connect to Dubbo Certificate Authority."); } else { logger.warn( CONFIG_SSL_CONNECT_INSECURE, "", "", - "Use insecure connection to connect to Dubbo Certificate Authority. Reason: No oidc token is provided."); + "Use insecure connection to connect to Dubbo Certificate" + + " Authority. Reason: No oidc token is provided."); } - return stub; - } - - /** - * Generate key pair with RSA - * - * @return key pair - */ - protected static KeyPair signWithRsa() { - KeyPair keyPair = null; - try { - KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA"); - kpGenerator.initialize(4096); - java.security.KeyPair keypair = kpGenerator.generateKeyPair(); - PublicKey publicKey = keypair.getPublic(); - PrivateKey privateKey = keypair.getPrivate(); - ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").build(keypair.getPrivate()); - keyPair = new KeyPair(publicKey, privateKey, signer); - } catch (NoSuchAlgorithmException | OperatorCreationException e) { - logger.error( - CONFIG_SSL_CERT_GENERATE_FAILED, - "", - "", - "Generate Key with SHA256WithRSA algorithm failed. Please check if your system support.", - e); - } - return keyPair; - } - - /** - * Generate key pair with ECDSA - * - * @return key pair - */ - protected static KeyPair signWithEcdsa() { - KeyPair keyPair = null; - try { - ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1"); - KeyPairGenerator g = KeyPairGenerator.getInstance("EC"); - g.initialize(ecSpec, new SecureRandom()); - java.security.KeyPair keypair = g.generateKeyPair(); - PublicKey publicKey = keypair.getPublic(); - PrivateKey privateKey = keypair.getPrivate(); - ContentSigner signer = new JcaContentSignerBuilder("SHA256withECDSA").build(privateKey); - keyPair = new KeyPair(publicKey, privateKey, signer); - } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | OperatorCreationException e) { - logger.error( - CONFIG_SSL_CERT_GENERATE_FAILED, - "", - "", - "Generate Key with secp256r1 algorithm failed. Please check if your system support. " - + "Will attempt to generate with RSA2048.", - e); - } - return keyPair; } private DubboCertificateRequest generateRequest(String csr) { diff --git a/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/CertDeployerListenerTest.java b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/CertDeployerListenerTest.java index 2fcfb19145..a5876c4918 100644 --- a/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/CertDeployerListenerTest.java +++ b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/CertDeployerListenerTest.java @@ -120,7 +120,7 @@ class CertDeployerListenerTest { ClassLoader newClassLoader = new ClassLoader(originClassLoader) { @Override public Class loadClass(String name) throws ClassNotFoundException { - if (name.startsWith("io.grpc.Channel")) { + if (name.startsWith("org.apache.dubbo.config.ReferenceConfig")) { throw new ClassNotFoundException("Test"); } return super.loadClass(name); diff --git a/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertManagerTest.java b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertManagerTest.java index bb07578af1..4501108874 100644 --- a/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertManagerTest.java +++ b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertManagerTest.java @@ -17,16 +17,20 @@ package org.apache.dubbo.security.cert; import org.apache.dubbo.auth.v1alpha1.DubboCertificateResponse; -import org.apache.dubbo.auth.v1alpha1.DubboCertificateServiceGrpc; +import org.apache.dubbo.auth.v1alpha1.DubboCertificateService; +import org.apache.dubbo.config.ReferenceConfig; +import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.RpcContextAttachment; import org.apache.dubbo.rpc.model.FrameworkModel; import java.io.IOException; +import java.util.Objects; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import io.grpc.Channel; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; @@ -78,7 +82,7 @@ class DubboCertManagerTest { Assertions.assertEquals( new CertConfig("127.0.0.1:30060", "kubernetes", "caCertPath", "oidc345"), certManager.certConfig); - certManager.channel = Mockito.mock(Channel.class); + certManager.setReference(Mockito.mock(ReferenceConfig.class)); certManager.connect(new CertConfig("error", null, "error", "error")); Assertions.assertEquals( new CertConfig("127.0.0.1:30060", "kubernetes", "caCertPath", "oidc345"), certManager.certConfig); @@ -113,8 +117,10 @@ class DubboCertManagerTest { DubboCertManager certManager = new DubboCertManager(frameworkModel); CertConfig certConfig = new CertConfig("127.0.0.1:30062", null, null, null); certManager.connect0(certConfig); - Assertions.assertNotNull(certManager.channel); - Assertions.assertEquals("127.0.0.1:30062", certManager.channel.authority()); + Assertions.assertNotNull(certManager.getDubboBootstrap()); + int endIndex = certManager.getReference().getUrl().indexOf("//"); + Assertions.assertEquals( + "127.0.0.1:30062", certManager.getReference().getUrl().substring(endIndex + 2)); frameworkModel.destroy(); } @@ -123,12 +129,14 @@ class DubboCertManagerTest { void testConnect2() { FrameworkModel frameworkModel = new FrameworkModel(); DubboCertManager certManager = new DubboCertManager(frameworkModel); - String file = - this.getClass().getClassLoader().getResource("certs/ca.crt").getFile(); + String file = Objects.requireNonNull(this.getClass().getClassLoader().getResource("certs/ca.crt")) + .getFile(); CertConfig certConfig = new CertConfig("127.0.0.1:30062", null, file, null); certManager.connect0(certConfig); - Assertions.assertNotNull(certManager.channel); - Assertions.assertEquals("127.0.0.1:30062", certManager.channel.authority()); + Assertions.assertNotNull(certManager.getReference()); + int endIndex = certManager.getReference().getUrl().indexOf("//"); + Assertions.assertEquals( + "127.0.0.1:30062", certManager.getReference().getUrl().substring(endIndex + 2)); frameworkModel.destroy(); } @@ -137,9 +145,7 @@ class DubboCertManagerTest { void testConnect3() { FrameworkModel frameworkModel = new FrameworkModel(); DubboCertManager certManager = new DubboCertManager(frameworkModel); - String file = this.getClass() - .getClassLoader() - .getResource("certs/broken-ca.crt") + String file = Objects.requireNonNull(this.getClass().getClassLoader().getResource("certs/broken-ca.crt")) .getFile(); CertConfig certConfig = new CertConfig("127.0.0.1:30062", null, file, null); Assertions.assertThrows(RuntimeException.class, () -> certManager.connect0(certConfig)); @@ -157,9 +163,9 @@ class DubboCertManagerTest { Assertions.assertNull(certManager.refreshFuture); Mockito.verify(scheduledFuture, Mockito.times(1)).cancel(true); - certManager.channel = Mockito.mock(Channel.class); + certManager.setReference(Mockito.mock(ReferenceConfig.class)); certManager.disConnect(); - Assertions.assertNull(certManager.channel); + Assertions.assertNull(certManager.getReference()); frameworkModel.destroy(); } @@ -174,7 +180,7 @@ class DubboCertManagerTest { certManager.certConfig = Mockito.mock(CertConfig.class); Assertions.assertFalse(certManager.isConnected()); - certManager.channel = Mockito.mock(Channel.class); + certManager.setReference(Mockito.mock(ReferenceConfig.class)); Assertions.assertFalse(certManager.isConnected()); certManager.certPair = Mockito.mock(CertPair.class); @@ -251,48 +257,49 @@ class DubboCertManagerTest { managerMock.when(DubboCertManager::signWithEcdsa).thenCallRealMethod(); - certManager.channel = Mockito.mock(Channel.class); - try (MockedStatic mockGrpc = - Mockito.mockStatic(DubboCertificateServiceGrpc.class, CALLS_REAL_METHODS)) { - DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub stub = - Mockito.mock(DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub.class); - mockGrpc.when(() -> DubboCertificateServiceGrpc.newBlockingStub(Mockito.any(Channel.class))) - .thenReturn(stub); - Mockito.when(stub.createCertificate(Mockito.any())) - .thenReturn(DubboCertificateResponse.newBuilder() - .setSuccess(false) - .build()); + certManager.setDubboBootstrap(Mockito.mock(DubboBootstrap.class)); + ReferenceConfig reference = Mockito.mock(ReferenceConfig.class); + certManager.setReference(reference); + DubboCertificateService dubboCertificateService = Mockito.mock(DubboCertificateService.class); + Mockito.when(reference.get()).thenReturn(dubboCertificateService); + Mockito.when(dubboCertificateService.createCertificate(Mockito.any())) + .thenReturn(DubboCertificateResponse.newBuilder() + .setSuccess(false) + .build()); - certManager.certConfig = new CertConfig(null, null, null, null); - Assertions.assertNull(certManager.refreshCert()); + certManager.certConfig = new CertConfig(null, null, null, null); + Assertions.assertNull(certManager.refreshCert()); - String file = this.getClass() - .getClassLoader() - .getResource("certs/token") - .getFile(); - Mockito.when(stub.withInterceptors(Mockito.any())).thenReturn(stub); + // Test setHeaderIfNeed() + String file = Objects.requireNonNull( + this.getClass().getClassLoader().getResource("certs/token")) + .getFile(); + try (MockedStatic mockContext = + Mockito.mockStatic(RpcContext.class, Mockito.CALLS_REAL_METHODS)) { + RpcContextAttachment rpcContextAttachment = Mockito.mock(RpcContextAttachment.class); + mockContext.when(RpcContext::getClientAttachment).thenReturn(rpcContextAttachment); certManager.certConfig = new CertConfig(null, null, null, file); - - Assertions.assertNull(certManager.refreshCert()); - Mockito.verify(stub, Mockito.times(1)).withInterceptors(Mockito.any()); - - Mockito.when(stub.createCertificate(Mockito.any())) - .thenReturn(DubboCertificateResponse.newBuilder() - .setSuccess(true) - .setCertPem("certPem") - .addTrustCerts("trustCerts") - .setExpireTime(123456) - .build()); - CertPair certPair = certManager.refreshCert(); - Assertions.assertNotNull(certPair); - Assertions.assertEquals("certPem", certPair.getCertificate()); - Assertions.assertEquals("trustCerts", certPair.getTrustCerts()); - Assertions.assertEquals(123456, certPair.getExpireTime()); - - Mockito.when(stub.createCertificate(Mockito.any())).thenReturn(null); Assertions.assertNull(certManager.refreshCert()); + Mockito.verify(rpcContextAttachment, Mockito.times(1)).setAttachment(Mockito.any(), Mockito.any()); } + Mockito.when(dubboCertificateService.createCertificate(Mockito.any())) + .thenReturn(DubboCertificateResponse.newBuilder() + .setSuccess(true) + .setCertPem("certPem") + .addTrustCerts("trustCerts") + .setExpireTime(123456) + .build()); + CertPair certPair = certManager.refreshCert(); + Assertions.assertNotNull(certPair); + Assertions.assertEquals("certPem", certPair.getCertificate()); + Assertions.assertEquals("trustCerts", certPair.getTrustCerts()); + Assertions.assertEquals(123456, certPair.getExpireTime()); + + Mockito.when(dubboCertificateService.createCertificate(Mockito.any())) + .thenReturn(null); + Assertions.assertNull(certManager.refreshCert()); + frameworkModel.destroy(); } }