From 02ad8afd29fedda2daf52eb6f3f9954d0c564887 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Sun, 26 Feb 2023 16:43:45 +0800 Subject: [PATCH 01/52] Add: add remoting/net member --- Cargo.toml | 18 ++- remoting/net/Cargo.toml | 17 ++ remoting/net/src/conn.rs | 298 +++++++++++++++++++++++++++++++++++ remoting/net/src/dial.rs | 138 ++++++++++++++++ remoting/net/src/incoming.rs | 94 +++++++++++ remoting/net/src/lib.rs | 79 ++++++++++ remoting/net/src/probe.rs | 63 ++++++++ remoting/net/src/tests.rs | 2 + 8 files changed, 708 insertions(+), 1 deletion(-) create mode 100644 remoting/net/Cargo.toml create mode 100644 remoting/net/src/conn.rs create mode 100644 remoting/net/src/dial.rs create mode 100644 remoting/net/src/incoming.rs create mode 100644 remoting/net/src/lib.rs create mode 100644 remoting/net/src/probe.rs create mode 100644 remoting/net/src/tests.rs diff --git a/Cargo.toml b/Cargo.toml index d4404f23..eef89fd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,5 +10,21 @@ members = [ "dubbo", "examples/echo", "examples/greeter", - "dubbo-build" + "dubbo-build", + "remoting/net" ] + + +[workspace.dependencies] +pin-project = "1" +tokio = "1.0" +tower = "0.4" +tokio-stream = "0.1" +tokio-util = "0.7" +socket2 = "0.4" +async-trait = "0.1" +dashmap = "5" +lazy_static = "1" +futures = "0.3" +tracing = "0.1" +tracing-subscriber = "0.3.15" \ No newline at end of file diff --git a/remoting/net/Cargo.toml b/remoting/net/Cargo.toml new file mode 100644 index 00000000..655a0f9b --- /dev/null +++ b/remoting/net/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "remoting" +version = "0.1.0" +edition = "2021" + + +[dependencies] +pin-project.workspace = true +tokio = { workspace = true, features = ["net", "time", "sync", "io-util"] } +tokio-stream = { workspace = true, features = ["net"] } +tower.workspace = true +socket2.workspace = true +async-trait.workspace = true +dashmap.workspace = true +lazy_static.workspace = true +futures.workspace = true +tracing.workspace = true \ No newline at end of file diff --git a/remoting/net/src/conn.rs b/remoting/net/src/conn.rs new file mode 100644 index 00000000..ed9efb78 --- /dev/null +++ b/remoting/net/src/conn.rs @@ -0,0 +1,298 @@ +use std::{ + io, + pin::Pin, + task::{Context, Poll}, +}; + +use pin_project::pin_project; +#[cfg(target_family = "unix")] +use tokio::net::{unix, UnixStream}; +use tokio::{ + io::{AsyncRead, AsyncWrite, ReadBuf}, + net::{tcp, TcpStream}, +}; + +use super::Address; + +#[derive(Clone)] +pub struct ConnInfo { + pub peer_addr: Option
, +} + +pub trait DynStream: AsyncRead + AsyncWrite + Send + 'static {} + +impl DynStream for T where T: AsyncRead + AsyncWrite + Send + 'static {} + +#[pin_project(project = IoStreamProj)] +pub enum ConnStream { + Tcp(#[pin] TcpStream), + #[cfg(target_family = "unix")] + Unix(#[pin] UnixStream), +} + +#[pin_project(project = OwnedWriteHalfProj)] +pub enum OwnedWriteHalf { + Tcp(#[pin] tcp::OwnedWriteHalf), + #[cfg(target_family = "unix")] + Unix(#[pin] unix::OwnedWriteHalf), +} + +impl AsyncWrite for OwnedWriteHalf { + #[inline] + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + match self.project() { + OwnedWriteHalfProj::Tcp(half) => half.poll_write(cx, buf), + #[cfg(target_family = "unix")] + OwnedWriteHalfProj::Unix(half) => half.poll_write(cx, buf), + } + } + + #[inline] + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + OwnedWriteHalfProj::Tcp(half) => half.poll_flush(cx), + #[cfg(target_family = "unix")] + OwnedWriteHalfProj::Unix(half) => half.poll_flush(cx), + } + } + + #[inline] + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + OwnedWriteHalfProj::Tcp(half) => half.poll_shutdown(cx), + #[cfg(target_family = "unix")] + OwnedWriteHalfProj::Unix(half) => half.poll_shutdown(cx), + } + } + + #[inline] + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[io::IoSlice<'_>], + ) -> Poll> { + match self.project() { + OwnedWriteHalfProj::Tcp(half) => half.poll_write_vectored(cx, bufs), + #[cfg(target_family = "unix")] + OwnedWriteHalfProj::Unix(half) => half.poll_write_vectored(cx, bufs), + } + } + + #[inline] + fn is_write_vectored(&self) -> bool { + match self { + Self::Tcp(half) => half.is_write_vectored(), + #[cfg(target_family = "unix")] + Self::Unix(half) => half.is_write_vectored(), + } + } +} + +#[pin_project(project = OwnedReadHalfProj)] +pub enum OwnedReadHalf { + Tcp(#[pin] tcp::OwnedReadHalf), + #[cfg(target_family = "unix")] + Unix(#[pin] unix::OwnedReadHalf), +} + +impl AsyncRead for OwnedReadHalf { + #[inline] + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + match self.project() { + OwnedReadHalfProj::Tcp(half) => half.poll_read(cx, buf), + #[cfg(target_family = "unix")] + OwnedReadHalfProj::Unix(half) => half.poll_read(cx, buf), + } + } +} + +impl ConnStream { + #[allow(clippy::type_complexity)] + pub fn into_split(self) -> (OwnedReadHalf, OwnedWriteHalf) { + match self { + Self::Tcp(stream) => { + let (rh, wh) = stream.into_split(); + (OwnedReadHalf::Tcp(rh), OwnedWriteHalf::Tcp(wh)) + } + #[cfg(target_family = "unix")] + Self::Unix(stream) => { + let (rh, wh) = stream.into_split(); + (OwnedReadHalf::Unix(rh), OwnedWriteHalf::Unix(wh)) + } + } + } +} + +impl From for ConnStream { + #[inline] + fn from(s: TcpStream) -> Self { + let _ = s.set_nodelay(true); + Self::Tcp(s) + } +} + +#[cfg(target_family = "unix")] +impl From for ConnStream { + #[inline] + fn from(s: UnixStream) -> Self { + Self::Unix(s) + } +} + +impl AsyncRead for ConnStream { + #[inline] + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + match self.project() { + IoStreamProj::Tcp(s) => s.poll_read(cx, buf), + #[cfg(target_family = "unix")] + IoStreamProj::Unix(s) => s.poll_read(cx, buf), + } + } +} + +impl AsyncWrite for ConnStream { + #[inline] + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + match self.project() { + IoStreamProj::Tcp(s) => s.poll_write(cx, buf), + #[cfg(target_family = "unix")] + IoStreamProj::Unix(s) => s.poll_write(cx, buf), + } + } + + #[inline] + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + IoStreamProj::Tcp(s) => s.poll_flush(cx), + #[cfg(target_family = "unix")] + IoStreamProj::Unix(s) => s.poll_flush(cx), + } + } + + #[inline] + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + IoStreamProj::Tcp(s) => s.poll_shutdown(cx), + #[cfg(target_family = "unix")] + IoStreamProj::Unix(s) => s.poll_shutdown(cx), + } + } + + #[inline] + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[io::IoSlice<'_>], + ) -> Poll> { + match self.project() { + IoStreamProj::Tcp(s) => s.poll_write_vectored(cx, bufs), + #[cfg(target_family = "unix")] + IoStreamProj::Unix(s) => s.poll_write_vectored(cx, bufs), + } + } + + #[inline] + fn is_write_vectored(&self) -> bool { + match self { + Self::Tcp(s) => s.is_write_vectored(), + #[cfg(target_family = "unix")] + Self::Unix(s) => s.is_write_vectored(), + } + } +} + +impl ConnStream { + #[inline] + pub fn peer_addr(&self) -> Option
{ + match self { + Self::Tcp(s) => s.peer_addr().map(Address::from).ok(), + #[cfg(target_family = "unix")] + Self::Unix(s) => s.peer_addr().ok().and_then(|s| Address::try_from(s).ok()), + } + } +} +pub struct Conn { + pub stream: ConnStream, + pub info: ConnInfo, +} + +impl Conn { + #[inline] + pub fn new(stream: ConnStream, info: ConnInfo) -> Self { + Conn { stream, info } + } +} + +impl From for Conn +where + T: Into, +{ + #[inline] + fn from(i: T) -> Self { + let i = i.into(); + let peer_addr = i.peer_addr(); + Conn::new(i, ConnInfo { peer_addr }) + } +} + +impl AsyncRead for Conn { + #[inline] + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.stream).poll_read(cx, buf) + } +} + +impl AsyncWrite for Conn { + #[inline] + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.stream).poll_write(cx, buf) + } + + #[inline] + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.stream).poll_flush(cx) + } + + #[inline] + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.stream).poll_shutdown(cx) + } + + #[inline] + fn poll_write_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[io::IoSlice<'_>], + ) -> Poll> { + Pin::new(&mut self.stream).poll_write_vectored(cx, bufs) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + self.stream.is_write_vectored() + } +} diff --git a/remoting/net/src/dial.rs b/remoting/net/src/dial.rs new file mode 100644 index 00000000..8e51279b --- /dev/null +++ b/remoting/net/src/dial.rs @@ -0,0 +1,138 @@ +use std::io; + +use socket2::{Domain, Protocol, Socket, Type}; +#[cfg(target_family = "unix")] +use tokio::net::UnixStream; +use tokio::{ + io::{AsyncRead, AsyncWrite}, + net::TcpSocket, + time::{timeout, Duration}, +}; + +use super::{ + conn::{Conn, OwnedReadHalf, OwnedWriteHalf}, + Address, +}; + +/// [`MakeTransport`] creates an [`AsyncRead`] and an [`AsyncWrite`] for the given [`Address`]. +#[async_trait::async_trait] +pub trait MakeTransport: Clone + Send + Sync + 'static { + type ReadHalf: AsyncRead + Send + Sync + Unpin + 'static; + type WriteHalf: AsyncWrite + Send + Sync + Unpin + 'static; + + async fn make_transport(&self, addr: Address) -> io::Result<(Self::ReadHalf, Self::WriteHalf)>; + fn set_connect_timeout(&mut self, timeout: Option); + fn set_read_timeout(&mut self, timeout: Option); + fn set_write_timeout(&mut self, timeout: Option); +} + +#[derive(Default, Debug, Clone, Copy)] +pub struct DefaultMakeTransport { + cfg: Config, +} + +#[derive(Default, Debug, Clone, Copy)] +pub struct Config { + pub connect_timeout: Option, + pub read_timeout: Option, + pub write_timeout: Option, +} + +impl Config { + pub fn new( + connect_timeout: Option, + read_timeout: Option, + write_timeout: Option, + ) -> Self { + Self { + connect_timeout, + read_timeout, + write_timeout, + } + } + + pub fn with_connect_timeout(mut self, timeout: Option) -> Self { + self.connect_timeout = timeout; + self + } + + pub fn with_read_timeout(mut self, timeout: Option) -> Self { + self.read_timeout = timeout; + self + } + + pub fn with_write_timeout(mut self, timeout: Option) -> Self { + self.write_timeout = timeout; + self + } +} + +impl DefaultMakeTransport { + pub fn new() -> Self { + Self::default() + } +} + +#[async_trait::async_trait] +impl MakeTransport for DefaultMakeTransport { + type ReadHalf = OwnedReadHalf; + + type WriteHalf = OwnedWriteHalf; + + async fn make_transport(&self, addr: Address) -> io::Result<(Self::ReadHalf, Self::WriteHalf)> { + let conn = self.make_connection(addr).await?; + let (read, write) = conn.stream.into_split(); + Ok((read, write)) + } + + fn set_connect_timeout(&mut self, timeout: Option) { + self.cfg = self.cfg.with_connect_timeout(timeout); + } + + fn set_read_timeout(&mut self, timeout: Option) { + self.cfg = self.cfg.with_read_timeout(timeout); + } + + fn set_write_timeout(&mut self, timeout: Option) { + self.cfg = self.cfg.with_write_timeout(timeout); + } +} + +impl DefaultMakeTransport { + pub async fn make_connection(&self, addr: Address) -> Result { + match addr { + Address::Ip(addr) => { + let stream = { + let domain = Domain::for_address(addr); + let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?; + socket.set_nonblocking(true)?; + socket.set_read_timeout(self.cfg.read_timeout)?; + socket.set_write_timeout(self.cfg.write_timeout)?; + + #[cfg(unix)] + let socket = unsafe { + use std::os::unix::io::{FromRawFd, IntoRawFd}; + TcpSocket::from_raw_fd(socket.into_raw_fd()) + }; + #[cfg(windows)] + let socket = unsafe { + use std::os::windows::io::{FromRawSocket, IntoRawSocket}; + TcpSocket::from_raw_socket(socket.into_raw_socket()) + }; + + let connect = socket.connect(addr); + + if let Some(conn_timeout) = self.cfg.connect_timeout { + timeout(conn_timeout, connect).await?? + } else { + connect.await? + } + }; + stream.set_nodelay(true)?; + Ok(Conn::from(stream)) + } + #[cfg(target_family = "unix")] + Address::Unix(addr) => UnixStream::connect(addr).await.map(Conn::from), + } + } +} diff --git a/remoting/net/src/incoming.rs b/remoting/net/src/incoming.rs new file mode 100644 index 00000000..82ea077d --- /dev/null +++ b/remoting/net/src/incoming.rs @@ -0,0 +1,94 @@ +use std::{ + fmt, io, + task::{Context, Poll}, +}; + +use futures::Stream; +use pin_project::pin_project; +use tokio::net::TcpListener; +#[cfg(target_family = "unix")] +use tokio::net::UnixListener; +#[cfg(target_family = "unix")] +use tokio_stream::wrappers::UnixListenerStream; +use tokio_stream::{wrappers::TcpListenerStream, StreamExt}; + +use super::{conn::Conn, Address}; + +#[pin_project(project = IncomingProj)] +#[derive(Debug)] +pub enum DefaultIncoming { + Tcp(#[pin] TcpListenerStream), + #[cfg(target_family = "unix")] + Unix(#[pin] UnixListenerStream), +} + +#[async_trait::async_trait] +impl MakeIncoming for DefaultIncoming { + type Incoming = DefaultIncoming; + + async fn make_incoming(self) -> io::Result { + Ok(self) + } +} + +#[cfg(target_family = "unix")] +impl From for DefaultIncoming { + fn from(l: UnixListener) -> Self { + DefaultIncoming::Unix(UnixListenerStream::new(l)) + } +} + +impl From for DefaultIncoming { + fn from(l: TcpListener) -> Self { + DefaultIncoming::Tcp(TcpListenerStream::new(l)) + } +} + +#[async_trait::async_trait] +pub trait Incoming: fmt::Debug + Send + 'static { + async fn accept(&mut self) -> io::Result>; +} + +#[async_trait::async_trait] +impl Incoming for DefaultIncoming { + async fn accept(&mut self) -> io::Result> { + if let Some(conn) = self.try_next().await? { + tracing::trace!("[Net] recv a connection from: {:?}", conn.info.peer_addr); + Ok(Some(conn)) + } else { + Ok(None) + } + } +} + +#[async_trait::async_trait] +pub trait MakeIncoming { + type Incoming: Incoming; + + async fn make_incoming(self) -> io::Result; +} + +#[async_trait::async_trait] +impl MakeIncoming for Address { + type Incoming = DefaultIncoming; + + async fn make_incoming(self) -> io::Result { + match self { + Address::Ip(addr) => TcpListener::bind(addr).await.map(DefaultIncoming::from), + #[cfg(target_family = "unix")] + Address::Unix(addr) => UnixListener::bind(addr).map(DefaultIncoming::from), + } + } +} + +impl Stream for DefaultIncoming { + type Item = io::Result; + + fn poll_next(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + IncomingProj::Tcp(s) => s.poll_next(cx).map_ok(Conn::from), + #[cfg(target_family = "unix")] + IncomingProj::Unix(s) => s.poll_next(cx).map_ok(Conn::from), + } + } +} diff --git a/remoting/net/src/lib.rs b/remoting/net/src/lib.rs new file mode 100644 index 00000000..dfcc8b6f --- /dev/null +++ b/remoting/net/src/lib.rs @@ -0,0 +1,79 @@ +pub mod conn; +pub mod dial; +pub mod incoming; +mod probe; +mod tests; + +use std::{borrow::Cow, fmt, net::Ipv6Addr, path::Path}; + +pub use incoming::{DefaultIncoming, MakeIncoming}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum Address { + Ip(std::net::SocketAddr), + #[cfg(target_family = "unix")] + Unix(Cow<'static, Path>), +} + +impl Address { + pub fn favor_dual_stack(self) -> Self { + match self { + Address::Ip(addr) => { + if addr.ip().is_unspecified() && should_favor_ipv6() { + Address::Ip((Ipv6Addr::UNSPECIFIED, addr.port()).into()) + } else { + self + } + } + #[cfg(target_family = "unix")] + _ => self, + } + } +} + +fn should_favor_ipv6() -> bool { + let probed = probe::probe(); + !probed.ipv4 || probed.ipv4_mapped_ipv6 +} + +impl fmt::Display for Address { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Address::Ip(addr) => write!(f, "{addr}"), + #[cfg(target_family = "unix")] + Address::Unix(path) => write!(f, "{}", path.display()), + } + } +} + +impl From for Address { + fn from(addr: std::net::SocketAddr) -> Self { + Address::Ip(addr) + } +} + +#[cfg(target_family = "unix")] +impl From> for Address { + fn from(addr: Cow<'static, Path>) -> Self { + Address::Unix(addr) + } +} + +#[cfg(target_family = "unix")] +impl TryFrom for Address { + type Error = std::io::Error; + + fn try_from(value: tokio::net::unix::SocketAddr) -> Result { + Ok(Address::Unix(Cow::Owned( + value + .as_pathname() + .ok_or_else(|| { + std::io::Error::new( + std::io::ErrorKind::Other, + "unix socket doesn't have an address", + ) + })? + .to_owned(), + ))) + } +} diff --git a/remoting/net/src/probe.rs b/remoting/net/src/probe.rs new file mode 100644 index 00000000..27367e14 --- /dev/null +++ b/remoting/net/src/probe.rs @@ -0,0 +1,63 @@ +use lazy_static::lazy_static; +use socket2::{Domain, Protocol, Socket, Type}; + +#[derive(Debug)] +pub struct IpStackCapability { + pub ipv4: bool, + pub ipv6: bool, + pub ipv4_mapped_ipv6: bool, +} + +impl IpStackCapability { + fn probe() -> Self { + IpStackCapability { + ipv4: Self::probe_ipv4(), + ipv6: Self::probe_ipv6(), + ipv4_mapped_ipv6: Self::probe_ipv4_mapped_ipv6(), + } + } + + fn probe_ipv4() -> bool { + let s = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)); + s.is_ok() + } + + fn probe_ipv6() -> bool { + let s = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP)); + let s = match s { + Ok(s) => s, + Err(_) => return false, + }; + // this error is ignored in go, follow their strategy + let _ = s.set_only_v6(true); + let addr: std::net::SocketAddr = ([0, 0, 0, 0, 0, 0, 0, 1], 0).into(); + s.bind(&addr.into()).is_ok() + } + + fn probe_ipv4_mapped_ipv6() -> bool { + let s = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP)); + let s = match s { + Ok(s) => s, + Err(_) => return false, + }; + !s.only_v6().unwrap_or(true) + } +} + +pub fn probe() -> &'static IpStackCapability { + lazy_static! { + static ref CAPABILITY: IpStackCapability = IpStackCapability::probe(); + } + &CAPABILITY +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[ignore] + fn tryout_probe() { + println!("{:?}", probe()); + } +} diff --git a/remoting/net/src/tests.rs b/remoting/net/src/tests.rs new file mode 100644 index 00000000..90a52c2d --- /dev/null +++ b/remoting/net/src/tests.rs @@ -0,0 +1,2 @@ +#[test] +fn test_client() {} From b3cb54a7c7f59aa3ce43ed48b0bcb5709dc158a9 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Sun, 26 Feb 2023 17:16:07 +0800 Subject: [PATCH 02/52] Add: add remoting/net member --- Cargo.toml | 2 +- remoting/net/Cargo.toml | 4 ++-- remoting/net/src/conn.rs | 17 +++++++++++++++++ remoting/net/src/dial.rs | 16 ++++++++++++++++ remoting/net/src/incoming.rs | 16 ++++++++++++++++ remoting/net/src/lib.rs | 17 +++++++++++++++++ remoting/net/src/probe.rs | 16 ++++++++++++++++ remoting/net/src/tests.rs | 35 +++++++++++++++++++++++++++++++++-- 8 files changed, 118 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eef89fd5..ff43a2b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,4 +27,4 @@ dashmap = "5" lazy_static = "1" futures = "0.3" tracing = "0.1" -tracing-subscriber = "0.3.15" \ No newline at end of file +tracing-subscriber = "0.3.15" diff --git a/remoting/net/Cargo.toml b/remoting/net/Cargo.toml index 655a0f9b..c39a362e 100644 --- a/remoting/net/Cargo.toml +++ b/remoting/net/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] pin-project.workspace = true -tokio = { workspace = true, features = ["net", "time", "sync", "io-util"] } +tokio = { workspace = true, features = ["net", "time", "sync", "io-util","test-util","macros"] } tokio-stream = { workspace = true, features = ["net"] } tower.workspace = true socket2.workspace = true @@ -14,4 +14,4 @@ async-trait.workspace = true dashmap.workspace = true lazy_static.workspace = true futures.workspace = true -tracing.workspace = true \ No newline at end of file +tracing.workspace = true diff --git a/remoting/net/src/conn.rs b/remoting/net/src/conn.rs index ed9efb78..7a3f14ac 100644 --- a/remoting/net/src/conn.rs +++ b/remoting/net/src/conn.rs @@ -1,3 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + use std::{ io, pin::Pin, diff --git a/remoting/net/src/dial.rs b/remoting/net/src/dial.rs index 8e51279b..704e7cd3 100644 --- a/remoting/net/src/dial.rs +++ b/remoting/net/src/dial.rs @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ use std::io; use socket2::{Domain, Protocol, Socket, Type}; diff --git a/remoting/net/src/incoming.rs b/remoting/net/src/incoming.rs index 82ea077d..7a730839 100644 --- a/remoting/net/src/incoming.rs +++ b/remoting/net/src/incoming.rs @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ use std::{ fmt, io, task::{Context, Poll}, diff --git a/remoting/net/src/lib.rs b/remoting/net/src/lib.rs index dfcc8b6f..b79f2321 100644 --- a/remoting/net/src/lib.rs +++ b/remoting/net/src/lib.rs @@ -1,3 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + pub mod conn; pub mod dial; pub mod incoming; diff --git a/remoting/net/src/probe.rs b/remoting/net/src/probe.rs index 27367e14..216afbe3 100644 --- a/remoting/net/src/probe.rs +++ b/remoting/net/src/probe.rs @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ use lazy_static::lazy_static; use socket2::{Domain, Protocol, Socket, Type}; diff --git a/remoting/net/src/tests.rs b/remoting/net/src/tests.rs index 90a52c2d..cc43444a 100644 --- a/remoting/net/src/tests.rs +++ b/remoting/net/src/tests.rs @@ -1,2 +1,33 @@ -#[test] -fn test_client() {} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +use crate::dial::DefaultMakeTransport; +use crate::Address; +use tokio::io::AsyncWriteExt; + +// listen by command: `nc -l 8858 -v` +#[tokio::test(flavor = "current_thread")] +async fn test_tcp_bytes_send() { + let transport = DefaultMakeTransport::new(); + let mut conn = transport + .make_connection(Address::Ip("127.0.0.1:8858".parse().unwrap())) + .await + .unwrap(); + conn.write_all("\n\rhello dubbo-rust\n\r".to_string().as_bytes()) + .await + .unwrap(); +} From b49eb4146e74e1f72f4f0ece9815383fec6ac39f Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Sun, 26 Feb 2023 23:24:25 +0800 Subject: [PATCH 03/52] Add: remoting/net/incoming --- remoting/net/src/conn.rs | 20 ++++++++++++++++++ remoting/net/src/incoming.rs | 29 ++++++++++++++++++++++++++ remoting/net/src/lib.rs | 2 +- remoting/net/src/{tests.rs => pool.rs} | 17 --------------- 4 files changed, 50 insertions(+), 18 deletions(-) rename remoting/net/src/{tests.rs => pool.rs} (61%) diff --git a/remoting/net/src/conn.rs b/remoting/net/src/conn.rs index 7a3f14ac..d015a8ec 100644 --- a/remoting/net/src/conn.rs +++ b/remoting/net/src/conn.rs @@ -313,3 +313,23 @@ impl AsyncWrite for Conn { self.stream.is_write_vectored() } } + +#[cfg(test)] +mod tests { + use crate::dial::DefaultMakeTransport; + use crate::Address; + use tokio::io::AsyncWriteExt; + + // listen by command: nc -l 8858 -v + #[tokio::test(flavor = "current_thread")] + async fn test_write_bytes() { + let transport = DefaultMakeTransport::new(); + let mut conn = transport + .make_connection(Address::Ip("127.0.0.1:8858".parse().unwrap())) + .await + .unwrap(); + conn.write_all("\n\rhello dubbo-rust\n\r".to_string().as_bytes()) + .await + .unwrap(); + } +} diff --git a/remoting/net/src/incoming.rs b/remoting/net/src/incoming.rs index 7a730839..cd8b5a5c 100644 --- a/remoting/net/src/incoming.rs +++ b/remoting/net/src/incoming.rs @@ -108,3 +108,32 @@ impl Stream for DefaultIncoming { } } } + +#[cfg(test)] +mod tests { + use tokio::net::TcpListener; + use tokio_stream::wrappers::TcpListenerStream; + use tracing::info; + + use crate::incoming::Incoming; + use crate::{DefaultIncoming, MakeIncoming}; + + #[tokio::test] + async fn test_read_bytes() { + let listener = TcpListener::bind("[::]:8081").await.unwrap(); + let incoming = DefaultIncoming::Tcp(TcpListenerStream::new(listener)) + .make_incoming() + .await + .unwrap(); + println!("[VOLO] server start at: {:?}", incoming); + let mut incoming = incoming; + loop { + let conn = incoming.accept().await.unwrap(); + if let Some(conn) = conn { + info!("[VOLO] recv a connection from: {:?}", conn.info.peer_addr); + } else { + info!("[VOLO] recv a connection from: None"); + } + } + } +} diff --git a/remoting/net/src/lib.rs b/remoting/net/src/lib.rs index b79f2321..38f95a26 100644 --- a/remoting/net/src/lib.rs +++ b/remoting/net/src/lib.rs @@ -18,8 +18,8 @@ pub mod conn; pub mod dial; pub mod incoming; +mod pool; mod probe; -mod tests; use std::{borrow::Cow, fmt, net::Ipv6Addr, path::Path}; diff --git a/remoting/net/src/tests.rs b/remoting/net/src/pool.rs similarity index 61% rename from remoting/net/src/tests.rs rename to remoting/net/src/pool.rs index cc43444a..2944f981 100644 --- a/remoting/net/src/tests.rs +++ b/remoting/net/src/pool.rs @@ -14,20 +14,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -use crate::dial::DefaultMakeTransport; -use crate::Address; -use tokio::io::AsyncWriteExt; - -// listen by command: `nc -l 8858 -v` -#[tokio::test(flavor = "current_thread")] -async fn test_tcp_bytes_send() { - let transport = DefaultMakeTransport::new(); - let mut conn = transport - .make_connection(Address::Ip("127.0.0.1:8858".parse().unwrap())) - .await - .unwrap(); - conn.write_all("\n\rhello dubbo-rust\n\r".to_string().as_bytes()) - .await - .unwrap(); -} From fbe02d6c66b81fe6091ffb5cd358cf186ce8db03 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 27 Feb 2023 10:28:36 +0800 Subject: [PATCH 04/52] Add: remoting/net/incoming --- config/src/protocol.rs | 4 ++-- remoting/net/src/conn.rs | 3 +-- remoting/net/src/incoming.rs | 36 ++++++++++++++++++++++-------------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/config/src/protocol.rs b/config/src/protocol.rs index cdc357ad..4a47ac98 100644 --- a/config/src/protocol.rs +++ b/config/src/protocol.rs @@ -73,10 +73,10 @@ impl ProtocolRetrieve for ProtocolConfig { fn get_protocol_or_default(&self, protocol_key: &str) -> Protocol { let result = self.get_protocol(protocol_key); if let Some(..) = result { - result.unwrap().clone() + result.unwrap() } else { let result = self.get_protocol(protocol_key); - if result.is_none() { + if let Some(..) = result { panic!("default triple protocol dose not defined.") } else { result.unwrap() diff --git a/remoting/net/src/conn.rs b/remoting/net/src/conn.rs index d015a8ec..c3155017 100644 --- a/remoting/net/src/conn.rs +++ b/remoting/net/src/conn.rs @@ -316,8 +316,7 @@ impl AsyncWrite for Conn { #[cfg(test)] mod tests { - use crate::dial::DefaultMakeTransport; - use crate::Address; + use crate::{dial::DefaultMakeTransport, Address}; use tokio::io::AsyncWriteExt; // listen by command: nc -l 8858 -v diff --git a/remoting/net/src/incoming.rs b/remoting/net/src/incoming.rs index cd8b5a5c..c04eeb8a 100644 --- a/remoting/net/src/incoming.rs +++ b/remoting/net/src/incoming.rs @@ -111,29 +111,37 @@ impl Stream for DefaultIncoming { #[cfg(test)] mod tests { - use tokio::net::TcpListener; + use tokio::{io::AsyncReadExt, net::TcpListener}; use tokio_stream::wrappers::TcpListenerStream; - use tracing::info; - use crate::incoming::Incoming; - use crate::{DefaultIncoming, MakeIncoming}; + use crate::{incoming::Incoming, DefaultIncoming, MakeIncoming}; #[tokio::test] async fn test_read_bytes() { - let listener = TcpListener::bind("[::]:8081").await.unwrap(); + let listener = TcpListener::bind("127.0.0.1:8858").await.unwrap(); let incoming = DefaultIncoming::Tcp(TcpListenerStream::new(listener)) .make_incoming() .await .unwrap(); - println!("[VOLO] server start at: {:?}", incoming); - let mut incoming = incoming; - loop { - let conn = incoming.accept().await.unwrap(); - if let Some(conn) = conn { - info!("[VOLO] recv a connection from: {:?}", conn.info.peer_addr); - } else { - info!("[VOLO] recv a connection from: None"); + println!("[Dubbo-Rust] server start at: {:?}", incoming); + let join_handle = tokio::spawn(async move { + let mut incoming = incoming; + match incoming.accept().await.unwrap() { + Some(mut conn) => { + println!("[VOLO] recv a connection from: {:?}", conn.info.peer_addr); + let mut buf = vec![0; 1024]; + let n = conn.read(&mut buf).await.unwrap(); + println!( + "[VOLO] recv a connection from: {:?}", + String::from_utf8(buf[..n].to_vec()).unwrap() + ); + } + None => { + println!("[VOLO] recv a connection from: None"); + } } - } + }); + tokio::time::sleep(std::time::Duration::from_secs(10)).await; + drop(join_handle); } } From d48ae45842cd80fa41ddab8f46aed58a1b2a0a87 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 27 Feb 2023 10:36:33 +0800 Subject: [PATCH 05/52] Add: License --- remoting/net/LICENSE | 202 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 remoting/net/LICENSE diff --git a/remoting/net/LICENSE b/remoting/net/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/remoting/net/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. From 8c4cbb42ecd58a5ba58f54705c886234eb256955 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 27 Feb 2023 13:06:16 +0800 Subject: [PATCH 06/52] Add: License --- remoting/net/src/incoming.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/remoting/net/src/incoming.rs b/remoting/net/src/incoming.rs index c04eeb8a..82672605 100644 --- a/remoting/net/src/incoming.rs +++ b/remoting/net/src/incoming.rs @@ -128,16 +128,19 @@ mod tests { let mut incoming = incoming; match incoming.accept().await.unwrap() { Some(mut conn) => { - println!("[VOLO] recv a connection from: {:?}", conn.info.peer_addr); + println!( + "[Dubbo-Rust] recv a connection from: {:?}", + conn.info.peer_addr + ); let mut buf = vec![0; 1024]; let n = conn.read(&mut buf).await.unwrap(); println!( - "[VOLO] recv a connection from: {:?}", + "[Dubbo-Rust] recv a connection from: {:?}", String::from_utf8(buf[..n].to_vec()).unwrap() ); } None => { - println!("[VOLO] recv a connection from: None"); + println!("[Dubbo-Rust] recv a connection from: None"); } } }); From 9ddb8d918b117af32ebdd156841d4e7f12eaa0ac Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 13:23:55 +0800 Subject: [PATCH 07/52] Rft: using subpackage to manage registry implementations for avoiding primary directory abuse. --- Cargo.toml | 3 +- .../echo/src/generated/grpc.examples.echo.rs | 179 ++++++++++++------ remoting/net/Cargo.toml | 10 +- .../net/benches/transport_benchmark/main.rs | 16 ++ remoting/net/src/incoming.rs | 10 +- 5 files changed, 147 insertions(+), 71 deletions(-) create mode 100644 remoting/net/benches/transport_benchmark/main.rs diff --git a/Cargo.toml b/Cargo.toml index ae339cd7..9ace07f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,12 +24,11 @@ async-trait = "0.1" dashmap = "5" lazy_static = "1" futures = "0.3" -tracing = "0.1" -tracing-subscriber = "0.3.15" serde = "1" serde_json = "1" urlencoding = "2.1.2" logger = {path="./common/logger"} anyhow = "1.0.66" dubbo = { path = "./dubbo/" } +bb8 = "0.8.0" diff --git a/examples/echo/src/generated/grpc.examples.echo.rs b/examples/echo/src/generated/grpc.examples.echo.rs index ccb385cd..8758f85a 100644 --- a/examples/echo/src/generated/grpc.examples.echo.rs +++ b/examples/echo/src/generated/grpc.examples.echo.rs @@ -40,12 +40,16 @@ pub mod echo_client { &mut self, request: Request, ) -> Result, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("UnaryEcho")); - let path = http::uri::PathAndQuery::from_static("/grpc.examples.echo.Echo/UnaryEcho"); + let path = http::uri::PathAndQuery::from_static( + "/grpc.examples.echo.Echo/UnaryEcho", + ); self.inner.unary(request, codec, path, invocation).await } /// ServerStreamingEcho is server side streaming. @@ -53,51 +57,51 @@ pub mod echo_client { &mut self, request: Request, ) -> Result>, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ServerStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ServerStreamingEcho", ); - self.inner - .server_streaming(request, codec, path, invocation) - .await + self.inner.server_streaming(request, codec, path, invocation).await } /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ClientStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ClientStreamingEcho", ); - self.inner - .client_streaming(request, codec, path, invocation) - .await + self.inner.client_streaming(request, codec, path, invocation).await } /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result>, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("BidirectionalStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", ); - self.inner - .bidi_streaming(request, codec, path, invocation) - .await + self.inner.bidi_streaming(request, codec, path, invocation).await } } } @@ -114,7 +118,9 @@ pub mod echo_server { request: Request, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: futures_util::Stream> + type ServerStreamingEchoStream: futures_util::Stream< + Item = Result, + > + Send + 'static; /// ServerStreamingEcho is server side streaming. @@ -128,14 +134,19 @@ pub mod echo_server { request: Request>, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: futures_util::Stream> + type BidirectionalStreamingEchoStream: futures_util::Stream< + Item = Result, + > + Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, request: Request>, - ) -> Result, dubbo::status::Status>; + ) -> Result< + Response, + dubbo::status::Status, + >; } /// Echo is the echo service. #[derive(Debug)] @@ -165,7 +176,10 @@ pub mod echo_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -178,18 +192,26 @@ pub mod echo_server { } impl UnarySvc for UnaryEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture, dubbo::status::Status>; - fn call(&mut self, request: Request) -> Self::Future { + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; + fn call( + &mut self, + request: Request, + ) -> Self::Future { let inner = self.inner.0.clone(); let fut = async move { inner.unary_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server.unary(UnaryEchoServer { inner }, req).await; Ok(res) }; @@ -200,22 +222,32 @@ pub mod echo_server { struct ServerStreamingEchoServer { inner: _Inner, } - impl ServerStreamingSvc for ServerStreamingEchoServer { + impl ServerStreamingSvc + for ServerStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; - type Future = - BoxFuture, dubbo::status::Status>; - fn call(&mut self, request: Request) -> Self::Future { + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; + fn call( + &mut self, + request: Request, + ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { inner.server_streaming_echo(request).await }; + let fut = async move { + inner.server_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server .server_streaming(ServerStreamingEchoServer { inner }, req) .await; @@ -228,23 +260,31 @@ pub mod echo_server { struct ClientStreamingEchoServer { inner: _Inner, } - impl ClientStreamingSvc for ClientStreamingEchoServer { + impl ClientStreamingSvc + for ClientStreamingEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture, dubbo::status::Status>; + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { inner.client_streaming_echo(request).await }; + let fut = async move { + inner.client_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server .client_streaming(ClientStreamingEchoServer { inner }, req) .await; @@ -257,41 +297,56 @@ pub mod echo_server { struct BidirectionalStreamingEchoServer { inner: _Inner, } - impl StreamingSvc for BidirectionalStreamingEchoServer { + impl StreamingSvc + for BidirectionalStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; - type Future = - BoxFuture, dubbo::status::Status>; + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = - async move { inner.bidirectional_streaming_echo(request).await }; + let fut = async move { + inner.bidirectional_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server - .bidi_streaming(BidirectionalStreamingEchoServer { inner }, req) + .bidi_streaming( + BidirectionalStreamingEchoServer { + inner, + }, + req, + ) .await; Ok(res) }; Box::pin(fut) } - _ => Box::pin(async move { - Ok(http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap()) - }), + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } } } } diff --git a/remoting/net/Cargo.toml b/remoting/net/Cargo.toml index c39a362e..c62082e0 100644 --- a/remoting/net/Cargo.toml +++ b/remoting/net/Cargo.toml @@ -1,12 +1,15 @@ [package] -name = "remoting" +name = "net" version = "0.1.0" edition = "2021" +[[bench]] +name = "transport_benchmark" +harness=false [dependencies] pin-project.workspace = true -tokio = { workspace = true, features = ["net", "time", "sync", "io-util","test-util","macros"] } +tokio = { workspace = true, features = ["net", "time", "sync", "io-util", "test-util", "macros"] } tokio-stream = { workspace = true, features = ["net"] } tower.workspace = true socket2.workspace = true @@ -14,4 +17,5 @@ async-trait.workspace = true dashmap.workspace = true lazy_static.workspace = true futures.workspace = true -tracing.workspace = true +logger.workspace = true +bb8.workspace = true diff --git a/remoting/net/benches/transport_benchmark/main.rs b/remoting/net/benches/transport_benchmark/main.rs new file mode 100644 index 00000000..2944f981 --- /dev/null +++ b/remoting/net/benches/transport_benchmark/main.rs @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ diff --git a/remoting/net/src/incoming.rs b/remoting/net/src/incoming.rs index 82672605..bca797e9 100644 --- a/remoting/net/src/incoming.rs +++ b/remoting/net/src/incoming.rs @@ -20,6 +20,7 @@ use std::{ }; use futures::Stream; +use logger::tracing; use pin_project::pin_project; use tokio::net::TcpListener; #[cfg(target_family = "unix")] @@ -111,6 +112,7 @@ impl Stream for DefaultIncoming { #[cfg(test)] mod tests { + use logger::tracing::debug; use tokio::{io::AsyncReadExt, net::TcpListener}; use tokio_stream::wrappers::TcpListenerStream; @@ -123,24 +125,24 @@ mod tests { .make_incoming() .await .unwrap(); - println!("[Dubbo-Rust] server start at: {:?}", incoming); + debug!("[Dubbo-Rust] server start at: {:?}", incoming); let join_handle = tokio::spawn(async move { let mut incoming = incoming; match incoming.accept().await.unwrap() { Some(mut conn) => { - println!( + debug!( "[Dubbo-Rust] recv a connection from: {:?}", conn.info.peer_addr ); let mut buf = vec![0; 1024]; let n = conn.read(&mut buf).await.unwrap(); - println!( + debug!( "[Dubbo-Rust] recv a connection from: {:?}", String::from_utf8(buf[..n].to_vec()).unwrap() ); } None => { - println!("[Dubbo-Rust] recv a connection from: None"); + debug!("[Dubbo-Rust] recv a connection from: None"); } } }); From 3e594faf7637f9eb180bb0ea60513ed35b6e6461 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 14:21:07 +0800 Subject: [PATCH 08/52] Ftr: add common/utils subpackage --- Cargo.toml | 8 +++++++- common/utils/Cargo.toml | 10 ++++++++++ common/utils/src/lib.rs | 17 +++++++++++++++++ common/utils/src/yaml_util.rs | 16 ++++++++++++++++ config/Cargo.toml | 10 +++++----- 5 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 common/utils/Cargo.toml create mode 100644 common/utils/src/lib.rs create mode 100644 common/utils/src/yaml_util.rs diff --git a/Cargo.toml b/Cargo.toml index 9ace07f6..06341845 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,7 @@ [workspace] members = [ + "common/logger", + "common/utils", "xds", "registry/zookeeper", "registry/nacos", @@ -28,7 +30,11 @@ serde = "1" serde_json = "1" urlencoding = "2.1.2" logger = {path="./common/logger"} +utils = {path="./common/utils"} anyhow = "1.0.66" dubbo = { path = "./dubbo/" } -bb8 = "0.8.0" +bb8 = "0.8.0" # A connecton pool based on tokio +serde_yaml = "0.9.4" # yaml file parser +once_cell = "1.16.0" + diff --git a/common/utils/Cargo.toml b/common/utils/Cargo.toml new file mode 100644 index 00000000..62be6f32 --- /dev/null +++ b/common/utils/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "utils" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde_yaml.workspace = true +serde = { workspace = true, features = ["derive"] } \ No newline at end of file diff --git a/common/utils/src/lib.rs b/common/utils/src/lib.rs new file mode 100644 index 00000000..f2ffa96a --- /dev/null +++ b/common/utils/src/lib.rs @@ -0,0 +1,17 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +pub mod yaml_util; diff --git a/common/utils/src/yaml_util.rs b/common/utils/src/yaml_util.rs new file mode 100644 index 00000000..2944f981 --- /dev/null +++ b/common/utils/src/yaml_util.rs @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ diff --git a/config/Cargo.toml b/config/Cargo.toml index 1eaa89cb..39797970 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -10,8 +10,8 @@ repository = "https://github.com/apache/dubbo-rust.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = {version="1.0.138", features = ["derive"]} -serde_yaml = "0.9.4" -tracing = "0.1" -lazy_static = "1.3.0" -once_cell = "1.16.0" +serde = { workspace = true, features = ["derive"] } +serde_yaml.workspace = true +lazy_static.workspace = true +once_cell.workspace = true +utils.workspace = true From b45d1bafba00a38236dd1934501647c04cf4c990 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 20:38:46 +0800 Subject: [PATCH 09/52] Ftr: add common/utils subpackage --- .github/workflows/github-actions.yml | 2 +- Cargo.toml | 1 + application.yaml | 19 ++++++++ common/logger/Cargo.toml | 2 +- common/utils/Cargo.toml | 5 ++- common/utils/src/lib.rs | 1 + common/utils/src/path_util.rs | 41 +++++++++++++++++ common/utils/src/yaml_util.rs | 39 ++++++++++++++++ common/utils/tests/application.yaml | 2 + config/Cargo.toml | 1 + config/src/config.rs | 44 +++++++------------ config/src/lib.rs | 13 +----- dubbo.yaml | 26 ----------- dubbo/Cargo.toml | 22 +++++----- dubbogo.yaml | 7 --- .../greeter/{dubbo.yaml => application.yaml} | 2 + scripts/ci-check.sh | 23 ---------- 17 files changed, 140 insertions(+), 110 deletions(-) create mode 100644 application.yaml create mode 100644 common/utils/src/path_util.rs create mode 100644 common/utils/tests/application.yaml delete mode 100644 dubbo.yaml delete mode 100644 dubbogo.yaml rename examples/greeter/{dubbo.yaml => application.yaml} (93%) delete mode 100755 scripts/ci-check.sh diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index e8881e01..b02b3bc9 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -94,5 +94,5 @@ jobs: ../../target/debug/greeter-client env: ZOOKEEPER_SERVERS: 127.0.0.1:2181 - DUBBO_CONFIG_PATH: ./dubbo.yaml + DUBBO_CONFIG_PATH: ./application.yaml working-directory: examples/greeter diff --git a/Cargo.toml b/Cargo.toml index 06341845..c879e4d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,5 +36,6 @@ dubbo = { path = "./dubbo/" } bb8 = "0.8.0" # A connecton pool based on tokio serde_yaml = "0.9.4" # yaml file parser once_cell = "1.16.0" +itertools = "0.10.1" diff --git a/application.yaml b/application.yaml new file mode 100644 index 00000000..7cd01252 --- /dev/null +++ b/application.yaml @@ -0,0 +1,19 @@ +logging: + level: INFO +dubbo: + protocols: + triple: + ip: 0.0.0.0 + port: '8888' + name: tri + registries: + demoZK: + protocol: zookeeper + address: 0.0.0.0:2181 + provider: + services: + GreeterProvider: + version: 1.0.0 + group: test + protocol: triple + interface: org.apache.dubbo.sample.tri.Greeter \ No newline at end of file diff --git a/common/logger/Cargo.toml b/common/logger/Cargo.toml index 14157bb1..578ddfef 100644 --- a/common/logger/Cargo.toml +++ b/common/logger/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" [dependencies] tracing = "0.1" -tracing-subscriber = "0.3" \ No newline at end of file +tracing-subscriber = "0.3" diff --git a/common/utils/Cargo.toml b/common/utils/Cargo.toml index 62be6f32..d2d004e3 100644 --- a/common/utils/Cargo.toml +++ b/common/utils/Cargo.toml @@ -7,4 +7,7 @@ edition = "2021" [dependencies] serde_yaml.workspace = true -serde = { workspace = true, features = ["derive"] } \ No newline at end of file +serde = { workspace = true, features = ["derive"] } +logger.workspace=true +project-root = "0.2.2" +anyhow.workspace=true \ No newline at end of file diff --git a/common/utils/src/lib.rs b/common/utils/src/lib.rs index f2ffa96a..47dbe626 100644 --- a/common/utils/src/lib.rs +++ b/common/utils/src/lib.rs @@ -14,4 +14,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +pub mod path_util; pub mod yaml_util; diff --git a/common/utils/src/path_util.rs b/common/utils/src/path_util.rs new file mode 100644 index 00000000..2386d72c --- /dev/null +++ b/common/utils/src/path_util.rs @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +use std::env; +use std::path::PathBuf; + +pub fn app_root_dir() -> PathBuf { + match project_root::get_project_root() { + // Cargo.lock file as app root dir + Ok(p) => p, + Err(_) => env::current_dir().unwrap(), + } +} + +#[cfg(test)] +mod tests { + use logger::tracing::info; + + use super::*; + + #[test] + fn test_app_root_dir() { + logger::init(); + let dir = app_root_dir().join("application.yaml"); + info!("dir: {}", dir.display()); + } +} diff --git a/common/utils/src/yaml_util.rs b/common/utils/src/yaml_util.rs index 2944f981..80de6f74 100644 --- a/common/utils/src/yaml_util.rs +++ b/common/utils/src/yaml_util.rs @@ -14,3 +14,42 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use std::fs; +use std::path::PathBuf; + +use anyhow::Error; +use serde_yaml::from_slice; + +use logger::tracing; + +// parse yaml file to structs +pub fn yaml_file_parser(path: PathBuf) -> Result +where + T: serde::de::DeserializeOwned + std::fmt::Debug, +{ + if !path.is_file() { + return Err(anyhow::anyhow!("path is not a file: {:?}", path)); + } + let data = fs::read(path.as_path())?; + tracing::debug!("config data: {:?}", String::from_utf8(data.clone())); + Ok(from_slice(&data).unwrap()) +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use crate::path_util::app_root_dir; + use crate::yaml_util::yaml_file_parser; + + #[test] + fn test_yaml_file_parser() { + let path = app_root_dir() + .join("common") + .join("utils") + .join("tests") + .join("application.yaml"); + let config = yaml_file_parser::>>(path).unwrap(); + println!("{:?}", config); + } +} diff --git a/common/utils/tests/application.yaml b/common/utils/tests/application.yaml new file mode 100644 index 00000000..ecfd4478 --- /dev/null +++ b/common/utils/tests/application.yaml @@ -0,0 +1,2 @@ +logging: + level: INFO diff --git a/config/Cargo.toml b/config/Cargo.toml index 39797970..b4e19d47 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -15,3 +15,4 @@ serde_yaml.workspace = true lazy_static.workspace = true once_cell.workspace = true utils.workspace = true +logger.workspace=true \ No newline at end of file diff --git a/config/src/config.rs b/config/src/config.rs index ed3a7140..eb44464f 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -15,16 +15,18 @@ * limitations under the License. */ -use std::{collections::HashMap, env, fs}; +use std::path::PathBuf; +use std::{collections::HashMap, env}; use crate::{protocol::Protocol, registry::RegistryConfig}; +use logger::tracing; use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; -use tracing::trace; +use utils::yaml_util::yaml_file_parser; use super::{protocol::ProtocolConfig, provider::ProviderConfig, service::ServiceConfig}; -pub const DUBBO_CONFIG_PATH: &str = "./dubbo.yaml"; +pub const DUBBO_CONFIG_PATH: &str = "application.yaml"; pub static GLOBAL_ROOT_CONFIG: OnceCell = OnceCell::new(); pub const DUBBO_CONFIG_PREFIX: &str = "dubbo"; @@ -78,14 +80,16 @@ impl RootConfig { err, DUBBO_CONFIG_PATH ); - DUBBO_CONFIG_PATH.to_string() + utils::path_util::app_root_dir() + .join(DUBBO_CONFIG_PATH) + .to_str() + .unwrap() + .to_string() } }; - tracing::info!("current path: {:?}", env::current_dir()); - let data = fs::read(config_path)?; - trace!("config data: {:?}", String::from_utf8(data.clone())); - let conf: HashMap = serde_yaml::from_slice(&data).unwrap(); + let conf: HashMap = + yaml_file_parser(PathBuf::new().join(config_path)).unwrap(); let root_config: RootConfig = conf.get(DUBBO_CONFIG_PREFIX).unwrap().clone(); tracing::debug!("origin config: {:?}", conf); Ok(root_config) @@ -181,27 +185,9 @@ mod tests { #[test] fn test_load() { - // case 1: read config yaml from default path - println!("current path: {:?}", env::current_dir()); + logger::init(); let r = RootConfig::new(); - r.load(); - } - - #[test] - fn test_load1() { - // case 2: read config yaml from path in env - println!("current path: {:?}", env::current_dir()); - let r = RootConfig::new(); - r.load(); - } - - #[test] - fn test_write_yaml() { - let mut r = RootConfig::new(); - r.test_config(); - let yaml = serde_yaml::to_string(&r).unwrap(); - println!("config data: {:?}", yaml); - - fs::write("./test_dubbo.yaml", yaml); + let r = r.load().unwrap(); + println!("{:#?}", r); } } diff --git a/config/src/lib.rs b/config/src/lib.rs index e56d933a..0748c667 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -15,19 +15,10 @@ * limitations under the License. */ +pub use config::*; + pub mod config; pub mod protocol; pub mod provider; pub mod registry; pub mod service; - -pub use config::*; - -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - let result = 2 + 2; - assert_eq!(result, 4); - } -} diff --git a/dubbo.yaml b/dubbo.yaml deleted file mode 100644 index e14b5301..00000000 --- a/dubbo.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: dubbo -service: - echo: - version: 1.0.0 - group: test - protocol: triple - registry: '' - serializer: json - protocol_configs: - triple: - ip: 0.0.0.0 - port: '8888' - name: triple - listener: tcp - # helloworld.Greeter: - # version: 1.0.0 - # group: test - # protocol: triple - # registry: '' - # serializer: json -protocols: - triple: - ip: 0.0.0.0 - port: '8888' - name: triple - listener: tcp diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml index b552b25a..5700e811 100644 --- a/dubbo/Cargo.toml +++ b/dubbo/Cargo.toml @@ -10,23 +10,22 @@ repository = "https://github.com/apache/dubbo-rust.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -hyper = { version = "0.14.19", features = ["full"]} +hyper = { version = "0.14.19", features = ["full"] } http = "0.2" tower-service = "0.3.1" http-body = "0.4.4" -tower = { version = "0.4.12", features = ["timeout"]} +tower = { version = "0.4.12", features = ["timeout"] } futures-util = "0.3.23" -futures-core ="0.3.23" -tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] } +futures-core = "0.3.23" +tokio = { version = "1.0", features = ["rt-multi-thread", "time", "fs", "macros", "net", "signal"] } prost = "0.10.4" -lazy_static = "1.3.0" async-trait = "0.1.56" tower-layer = "0.3" bytes = "1.0" -pin-project = "1.0" +pin-project.workspace = true rand = "0.8.5" -serde_json = "1.0.82" -serde = {version="1.0.138", features = ["derive"]} +serde_json.workspace = true +serde = { workspace = true, features = ["derive"] } futures = "0.3" tracing = "0.1" tracing-subscriber = "0.3.15" @@ -34,10 +33,11 @@ axum = "0.5.9" async-stream = "0.3" flate2 = "1.0" aws-smithy-http = "0.54.1" -itertools = "0.10.1" -urlencoding = "2.1.2" +itertools.workspace = true +urlencoding.workspace = true +lazy_static.workspace = true -dubbo-config = {path = "../config", version = "0.3.0" } +dubbo-config = { path = "../config", version = "0.3.0" } #对象存储 state = { version = "0.5", features = ["tls"] } diff --git a/dubbogo.yaml b/dubbogo.yaml deleted file mode 100644 index 2e6fe5ba..00000000 --- a/dubbogo.yaml +++ /dev/null @@ -1,7 +0,0 @@ -dubbo: - consumer: - references: - GreeterClientImpl: - protocol: tri - url: "tri://localhost:8889" - interface: helloworld.Greeter \ No newline at end of file diff --git a/examples/greeter/dubbo.yaml b/examples/greeter/application.yaml similarity index 93% rename from examples/greeter/dubbo.yaml rename to examples/greeter/application.yaml index 96daf95c..6683c6d1 100644 --- a/examples/greeter/dubbo.yaml +++ b/examples/greeter/application.yaml @@ -1,3 +1,5 @@ +logging: + level: INFO dubbo: protocols: triple: diff --git a/scripts/ci-check.sh b/scripts/ci-check.sh deleted file mode 100755 index 5ffd46d8..00000000 --- a/scripts/ci-check.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -#/* -# * Licensed to the Apache Software Foundation (ASF) under one or more -# * contributor license agreements. See the NOTICE file distributed with -# * this work for additional information regarding copyright ownership. -# * The ASF licenses this file to You 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. -# */ - -cargo fmt --all -- --check -# use stable channel -cargo check -target/debug/greeter-server && target/debug/greeter-client && sleep 3s ; From 05095fa37252dfc7a5e98d76417df94065cc1c76 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 20:42:37 +0800 Subject: [PATCH 10/52] Ftr: add common/utils subpackage --- common/utils/src/path_util.rs | 3 +- common/utils/src/yaml_util.rs | 6 +- config/src/config.rs | 3 +- .../echo/src/generated/grpc.examples.echo.rs | 179 ++++++------------ 4 files changed, 66 insertions(+), 125 deletions(-) diff --git a/common/utils/src/path_util.rs b/common/utils/src/path_util.rs index 2386d72c..74fdf625 100644 --- a/common/utils/src/path_util.rs +++ b/common/utils/src/path_util.rs @@ -15,8 +15,7 @@ * limitations under the License. */ -use std::env; -use std::path::PathBuf; +use std::{env, path::PathBuf}; pub fn app_root_dir() -> PathBuf { match project_root::get_project_root() { diff --git a/common/utils/src/yaml_util.rs b/common/utils/src/yaml_util.rs index 80de6f74..4cc5b6a2 100644 --- a/common/utils/src/yaml_util.rs +++ b/common/utils/src/yaml_util.rs @@ -14,8 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use std::fs; -use std::path::PathBuf; +use std::{fs, path::PathBuf}; use anyhow::Error; use serde_yaml::from_slice; @@ -39,8 +38,7 @@ where mod tests { use std::collections::HashMap; - use crate::path_util::app_root_dir; - use crate::yaml_util::yaml_file_parser; + use crate::{path_util::app_root_dir, yaml_util::yaml_file_parser}; #[test] fn test_yaml_file_parser() { diff --git a/config/src/config.rs b/config/src/config.rs index eb44464f..f63b490c 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -15,8 +15,7 @@ * limitations under the License. */ -use std::path::PathBuf; -use std::{collections::HashMap, env}; +use std::{collections::HashMap, env, path::PathBuf}; use crate::{protocol::Protocol, registry::RegistryConfig}; use logger::tracing; diff --git a/examples/echo/src/generated/grpc.examples.echo.rs b/examples/echo/src/generated/grpc.examples.echo.rs index 8758f85a..ccb385cd 100644 --- a/examples/echo/src/generated/grpc.examples.echo.rs +++ b/examples/echo/src/generated/grpc.examples.echo.rs @@ -40,16 +40,12 @@ pub mod echo_client { &mut self, request: Request, ) -> Result, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("UnaryEcho")); - let path = http::uri::PathAndQuery::from_static( - "/grpc.examples.echo.Echo/UnaryEcho", - ); + let path = http::uri::PathAndQuery::from_static("/grpc.examples.echo.Echo/UnaryEcho"); self.inner.unary(request, codec, path, invocation).await } /// ServerStreamingEcho is server side streaming. @@ -57,51 +53,51 @@ pub mod echo_client { &mut self, request: Request, ) -> Result>, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ServerStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ServerStreamingEcho", ); - self.inner.server_streaming(request, codec, path, invocation).await + self.inner + .server_streaming(request, codec, path, invocation) + .await } /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ClientStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ClientStreamingEcho", ); - self.inner.client_streaming(request, codec, path, invocation).await + self.inner + .client_streaming(request, codec, path, invocation) + .await } /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result>, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("BidirectionalStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", ); - self.inner.bidi_streaming(request, codec, path, invocation).await + self.inner + .bidi_streaming(request, codec, path, invocation) + .await } } } @@ -118,9 +114,7 @@ pub mod echo_server { request: Request, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: futures_util::Stream< - Item = Result, - > + type ServerStreamingEchoStream: futures_util::Stream> + Send + 'static; /// ServerStreamingEcho is server side streaming. @@ -134,19 +128,14 @@ pub mod echo_server { request: Request>, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: futures_util::Stream< - Item = Result, - > + type BidirectionalStreamingEchoStream: futures_util::Stream> + Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, request: Request>, - ) -> Result< - Response, - dubbo::status::Status, - >; + ) -> Result, dubbo::status::Status>; } /// Echo is the echo service. #[derive(Debug)] @@ -176,10 +165,7 @@ pub mod echo_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready( - &mut self, - _cx: &mut Context<'_>, - ) -> Poll> { + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -192,26 +178,18 @@ pub mod echo_server { } impl UnarySvc for UnaryEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; - fn call( - &mut self, - request: Request, - ) -> Self::Future { + type Future = BoxFuture, dubbo::status::Status>; + fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.0.clone(); let fut = async move { inner.unary_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server.unary(UnaryEchoServer { inner }, req).await; Ok(res) }; @@ -222,32 +200,22 @@ pub mod echo_server { struct ServerStreamingEchoServer { inner: _Inner, } - impl ServerStreamingSvc - for ServerStreamingEchoServer { + impl ServerStreamingSvc for ServerStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; - fn call( - &mut self, - request: Request, - ) -> Self::Future { + type Future = + BoxFuture, dubbo::status::Status>; + fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.server_streaming_echo(request).await - }; + let fut = async move { inner.server_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server .server_streaming(ServerStreamingEchoServer { inner }, req) .await; @@ -260,31 +228,23 @@ pub mod echo_server { struct ClientStreamingEchoServer { inner: _Inner, } - impl ClientStreamingSvc - for ClientStreamingEchoServer { + impl ClientStreamingSvc for ClientStreamingEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; + type Future = BoxFuture, dubbo::status::Status>; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.client_streaming_echo(request).await - }; + let fut = async move { inner.client_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server .client_streaming(ClientStreamingEchoServer { inner }, req) .await; @@ -297,56 +257,41 @@ pub mod echo_server { struct BidirectionalStreamingEchoServer { inner: _Inner, } - impl StreamingSvc - for BidirectionalStreamingEchoServer { + impl StreamingSvc for BidirectionalStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; + type Future = + BoxFuture, dubbo::status::Status>; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.bidirectional_streaming_echo(request).await - }; + let fut = + async move { inner.bidirectional_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server - .bidi_streaming( - BidirectionalStreamingEchoServer { - inner, - }, - req, - ) + .bidi_streaming(BidirectionalStreamingEchoServer { inner }, req) .await; Ok(res) }; Box::pin(fut) } - _ => { - Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap(), - ) - }) - } + _ => Box::pin(async move { + Ok(http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap()) + }), } } } From 11139c647f5ae90cef7e869b9991e1b22df6a869 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 21:56:01 +0800 Subject: [PATCH 11/52] Ftr: add common/utils subpackage --- application.yaml | 2 +- common/logger/Cargo.toml | 2 + common/logger/src/level.rs | 23 +++ common/logger/src/lib.rs | 16 +- common/logger/src/tracing_configurer.rs | 38 ++-- common/utils/Cargo.toml | 4 +- common/utils/src/path_util.rs | 4 +- common/utils/src/yaml_util.rs | 49 ++++- common/utils/tests/application.yaml | 2 + .../echo/src/generated/grpc.examples.echo.rs | 179 ++++++++++++------ 10 files changed, 225 insertions(+), 94 deletions(-) create mode 100644 common/logger/src/level.rs diff --git a/application.yaml b/application.yaml index 7cd01252..0de344e9 100644 --- a/application.yaml +++ b/application.yaml @@ -1,5 +1,5 @@ logging: - level: INFO + level: debug dubbo: protocols: triple: diff --git a/common/logger/Cargo.toml b/common/logger/Cargo.toml index 578ddfef..e965706e 100644 --- a/common/logger/Cargo.toml +++ b/common/logger/Cargo.toml @@ -8,3 +8,5 @@ edition = "2021" [dependencies] tracing = "0.1" tracing-subscriber = "0.3" +once_cell.workspace = true +utils.workspace = true \ No newline at end of file diff --git a/common/logger/src/level.rs b/common/logger/src/level.rs new file mode 100644 index 00000000..f5c2da9f --- /dev/null +++ b/common/logger/src/level.rs @@ -0,0 +1,23 @@ +use crate::Level; + +pub(crate) struct LevelWrapper { + pub(crate) inner: Level, +} +impl LevelWrapper { + pub fn new(level: Level) -> Self { + LevelWrapper { inner: level } + } +} + +impl From for LevelWrapper { + fn from(s: String) -> Self { + match s.to_lowercase().as_str().trim() { + "error" => LevelWrapper::new(Level::ERROR), + "warn" => LevelWrapper::new(Level::WARN), + "info" => LevelWrapper::new(Level::INFO), + "debug" => LevelWrapper::new(Level::DEBUG), + "trace" => LevelWrapper::new(Level::TRACE), + _ => LevelWrapper::new(Level::INFO), + } + } +} diff --git a/common/logger/src/lib.rs b/common/logger/src/lib.rs index 27372747..6edce9f0 100644 --- a/common/logger/src/lib.rs +++ b/common/logger/src/lib.rs @@ -15,22 +15,32 @@ * limitations under the License. */ +use std::sync::atomic::{AtomicBool, Ordering}; + pub use tracing::{self, Level}; +// flag for the sake of avoiding multiple initialization +static TRACING_CONFIGURED: AtomicBool = AtomicBool::new(false); + +mod level; mod tracing_configurer; // put on main method pub fn init() { - tracing_configurer::default() + if !TRACING_CONFIGURED.load(Ordering::SeqCst) { + tracing_configurer::default() + } } #[cfg(test)] mod tests { - use tracing::debug; + use tracing::{debug, info, trace}; #[test] fn test_print_info_log() { super::init(); - debug!("hello rust"); + debug!("hello rust:debug"); + trace!("hello rust:trace"); + info!("hello rust:info"); } } diff --git a/common/logger/src/tracing_configurer.rs b/common/logger/src/tracing_configurer.rs index 40b1e844..4c30581b 100644 --- a/common/logger/src/tracing_configurer.rs +++ b/common/logger/src/tracing_configurer.rs @@ -17,27 +17,25 @@ // https://github.com/tokio-rs/tracing/issues/971 -use tracing::{debug, Level}; +use crate::level::LevelWrapper; +use std::path::PathBuf; +use tracing::debug; +use utils::path_util; +use utils::yaml_util; pub(crate) fn default() { - if let Some(true) = configured() { - parse_from_config() - } else { - tracing_subscriber::fmt() - .compact() - .with_line_number(true) - .with_max_level(Level::DEBUG) - // sets this to be the default, global collector for this application. - .try_init() - .expect("init err."); - } + let path_buf = PathBuf::new() + .join(path_util::app_root_dir()) + .join("application.yaml"); + let level: LevelWrapper = yaml_util::yaml_key_reader(path_buf, "logging.level") + .unwrap() + .into(); + tracing_subscriber::fmt() + .compact() + .with_line_number(true) + .with_max_level(level.inner) + // sets this to be the default, global collector for this application. + .try_init() + .expect("init err."); debug!("Tracing configured.") } - -pub(crate) fn parse_from_config() { - todo!() -} - -pub(crate) fn configured() -> Option { - None -} diff --git a/common/utils/Cargo.toml b/common/utils/Cargo.toml index d2d004e3..4665ab6d 100644 --- a/common/utils/Cargo.toml +++ b/common/utils/Cargo.toml @@ -8,6 +8,6 @@ edition = "2021" [dependencies] serde_yaml.workspace = true serde = { workspace = true, features = ["derive"] } -logger.workspace=true project-root = "0.2.2" -anyhow.workspace=true \ No newline at end of file +anyhow.workspace=true +once_cell.workspace = true \ No newline at end of file diff --git a/common/utils/src/path_util.rs b/common/utils/src/path_util.rs index 74fdf625..347f1088 100644 --- a/common/utils/src/path_util.rs +++ b/common/utils/src/path_util.rs @@ -27,14 +27,12 @@ pub fn app_root_dir() -> PathBuf { #[cfg(test)] mod tests { - use logger::tracing::info; use super::*; #[test] fn test_app_root_dir() { - logger::init(); let dir = app_root_dir().join("application.yaml"); - info!("dir: {}", dir.display()); + println!("dir: {}", dir.display()); } } diff --git a/common/utils/src/yaml_util.rs b/common/utils/src/yaml_util.rs index 4cc5b6a2..575530e3 100644 --- a/common/utils/src/yaml_util.rs +++ b/common/utils/src/yaml_util.rs @@ -14,12 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use std::collections::HashMap; +use std::sync::Mutex; use std::{fs, path::PathBuf}; use anyhow::Error; -use serde_yaml::from_slice; +use once_cell::sync::Lazy; +use serde_yaml::{from_slice, Value}; -use logger::tracing; +static YAML_VALUE_CACHE_MAP: Lazy>> = + Lazy::new(|| Mutex::new(HashMap::new())); // parse yaml file to structs pub fn yaml_file_parser(path: PathBuf) -> Result @@ -30,14 +34,40 @@ where return Err(anyhow::anyhow!("path is not a file: {:?}", path)); } let data = fs::read(path.as_path())?; - tracing::debug!("config data: {:?}", String::from_utf8(data.clone())); Ok(from_slice(&data).unwrap()) } +// read value by a key like: logging.level +pub fn yaml_key_reader(path: PathBuf, key: &str) -> Result, Error> { + if !path.is_file() { + return Err(anyhow::anyhow!("path is not a file: {:?}", path)); + } + let cache_map = YAML_VALUE_CACHE_MAP.lock().unwrap(); + let split_keys = key.split('.'); + let data = fs::read(path.as_path())?; + let mut value: Value; + match cache_map.contains_key(path.as_path()) { + true => { + value = cache_map.get(path.as_path()).unwrap().clone(); + } + false => { + value = from_slice(&data).unwrap(); + } + } + for key in split_keys { + value = value[key].clone(); + } + if value.is_null() { + return Ok(None); + } + Ok(Some(value.as_str().unwrap().to_string())) +} + #[cfg(test)] mod tests { use std::collections::HashMap; + use crate::yaml_util::yaml_key_reader; use crate::{path_util::app_root_dir, yaml_util::yaml_file_parser}; #[test] @@ -50,4 +80,17 @@ mod tests { let config = yaml_file_parser::>>(path).unwrap(); println!("{:?}", config); } + + #[test] + fn test_yaml_key_reader() { + let path = app_root_dir() + .join("common") + .join("utils") + .join("tests") + .join("application.yaml"); + let config = yaml_key_reader(path.clone(), "logging.level").unwrap(); + println!("{:?}", config); + let config = yaml_key_reader(path, "logging.file.path").unwrap(); + println!("{:?}", config); + } } diff --git a/common/utils/tests/application.yaml b/common/utils/tests/application.yaml index ecfd4478..a40e4fe3 100644 --- a/common/utils/tests/application.yaml +++ b/common/utils/tests/application.yaml @@ -1,2 +1,4 @@ logging: level: INFO + file: + path: /tmp/test.log diff --git a/examples/echo/src/generated/grpc.examples.echo.rs b/examples/echo/src/generated/grpc.examples.echo.rs index ccb385cd..8758f85a 100644 --- a/examples/echo/src/generated/grpc.examples.echo.rs +++ b/examples/echo/src/generated/grpc.examples.echo.rs @@ -40,12 +40,16 @@ pub mod echo_client { &mut self, request: Request, ) -> Result, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("UnaryEcho")); - let path = http::uri::PathAndQuery::from_static("/grpc.examples.echo.Echo/UnaryEcho"); + let path = http::uri::PathAndQuery::from_static( + "/grpc.examples.echo.Echo/UnaryEcho", + ); self.inner.unary(request, codec, path, invocation).await } /// ServerStreamingEcho is server side streaming. @@ -53,51 +57,51 @@ pub mod echo_client { &mut self, request: Request, ) -> Result>, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ServerStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ServerStreamingEcho", ); - self.inner - .server_streaming(request, codec, path, invocation) - .await + self.inner.server_streaming(request, codec, path, invocation).await } /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ClientStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ClientStreamingEcho", ); - self.inner - .client_streaming(request, codec, path, invocation) - .await + self.inner.client_streaming(request, codec, path, invocation).await } /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result>, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("BidirectionalStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", ); - self.inner - .bidi_streaming(request, codec, path, invocation) - .await + self.inner.bidi_streaming(request, codec, path, invocation).await } } } @@ -114,7 +118,9 @@ pub mod echo_server { request: Request, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: futures_util::Stream> + type ServerStreamingEchoStream: futures_util::Stream< + Item = Result, + > + Send + 'static; /// ServerStreamingEcho is server side streaming. @@ -128,14 +134,19 @@ pub mod echo_server { request: Request>, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: futures_util::Stream> + type BidirectionalStreamingEchoStream: futures_util::Stream< + Item = Result, + > + Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, request: Request>, - ) -> Result, dubbo::status::Status>; + ) -> Result< + Response, + dubbo::status::Status, + >; } /// Echo is the echo service. #[derive(Debug)] @@ -165,7 +176,10 @@ pub mod echo_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -178,18 +192,26 @@ pub mod echo_server { } impl UnarySvc for UnaryEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture, dubbo::status::Status>; - fn call(&mut self, request: Request) -> Self::Future { + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; + fn call( + &mut self, + request: Request, + ) -> Self::Future { let inner = self.inner.0.clone(); let fut = async move { inner.unary_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server.unary(UnaryEchoServer { inner }, req).await; Ok(res) }; @@ -200,22 +222,32 @@ pub mod echo_server { struct ServerStreamingEchoServer { inner: _Inner, } - impl ServerStreamingSvc for ServerStreamingEchoServer { + impl ServerStreamingSvc + for ServerStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; - type Future = - BoxFuture, dubbo::status::Status>; - fn call(&mut self, request: Request) -> Self::Future { + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; + fn call( + &mut self, + request: Request, + ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { inner.server_streaming_echo(request).await }; + let fut = async move { + inner.server_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server .server_streaming(ServerStreamingEchoServer { inner }, req) .await; @@ -228,23 +260,31 @@ pub mod echo_server { struct ClientStreamingEchoServer { inner: _Inner, } - impl ClientStreamingSvc for ClientStreamingEchoServer { + impl ClientStreamingSvc + for ClientStreamingEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture, dubbo::status::Status>; + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { inner.client_streaming_echo(request).await }; + let fut = async move { + inner.client_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server .client_streaming(ClientStreamingEchoServer { inner }, req) .await; @@ -257,41 +297,56 @@ pub mod echo_server { struct BidirectionalStreamingEchoServer { inner: _Inner, } - impl StreamingSvc for BidirectionalStreamingEchoServer { + impl StreamingSvc + for BidirectionalStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; - type Future = - BoxFuture, dubbo::status::Status>; + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = - async move { inner.bidirectional_streaming_echo(request).await }; + let fut = async move { + inner.bidirectional_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server - .bidi_streaming(BidirectionalStreamingEchoServer { inner }, req) + .bidi_streaming( + BidirectionalStreamingEchoServer { + inner, + }, + req, + ) .await; Ok(res) }; Box::pin(fut) } - _ => Box::pin(async move { - Ok(http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap()) - }), + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } } } } From d3a048afe8f8b4a2f1e09b41763b31917ec3bf1e Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 22:03:34 +0800 Subject: [PATCH 12/52] Ftr: add common/utils subpackage --- common/logger/src/level.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/common/logger/src/level.rs b/common/logger/src/level.rs index f5c2da9f..5a081ff0 100644 --- a/common/logger/src/level.rs +++ b/common/logger/src/level.rs @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ use crate::Level; pub(crate) struct LevelWrapper { From e777e6bea1b2a7e11e36a022f45aede7e697275e Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 22:08:10 +0800 Subject: [PATCH 13/52] Ftr: add common/utils subpackage --- common/utils/LICENSE | 202 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 common/utils/LICENSE diff --git a/common/utils/LICENSE b/common/utils/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/common/utils/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. From 319868c5adbb9e5833d30cae03bdcb2ed28b8749 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 22:13:49 +0800 Subject: [PATCH 14/52] Ftr: add common/utils subpackage --- common/logger/src/tracing_configurer.rs | 3 +- common/utils/src/yaml_util.rs | 10 +- .../echo/src/generated/grpc.examples.echo.rs | 179 ++++++------------ 3 files changed, 68 insertions(+), 124 deletions(-) diff --git a/common/logger/src/tracing_configurer.rs b/common/logger/src/tracing_configurer.rs index 4c30581b..1e2081f8 100644 --- a/common/logger/src/tracing_configurer.rs +++ b/common/logger/src/tracing_configurer.rs @@ -20,8 +20,7 @@ use crate::level::LevelWrapper; use std::path::PathBuf; use tracing::debug; -use utils::path_util; -use utils::yaml_util; +use utils::{path_util, yaml_util}; pub(crate) fn default() { let path_buf = PathBuf::new() diff --git a/common/utils/src/yaml_util.rs b/common/utils/src/yaml_util.rs index 575530e3..f8e0adfe 100644 --- a/common/utils/src/yaml_util.rs +++ b/common/utils/src/yaml_util.rs @@ -14,9 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use std::collections::HashMap; -use std::sync::Mutex; -use std::{fs, path::PathBuf}; +use std::{collections::HashMap, fs, path::PathBuf, sync::Mutex}; use anyhow::Error; use once_cell::sync::Lazy; @@ -67,8 +65,10 @@ pub fn yaml_key_reader(path: PathBuf, key: &str) -> Result, Error mod tests { use std::collections::HashMap; - use crate::yaml_util::yaml_key_reader; - use crate::{path_util::app_root_dir, yaml_util::yaml_file_parser}; + use crate::{ + path_util::app_root_dir, + yaml_util::{yaml_file_parser, yaml_key_reader}, + }; #[test] fn test_yaml_file_parser() { diff --git a/examples/echo/src/generated/grpc.examples.echo.rs b/examples/echo/src/generated/grpc.examples.echo.rs index 8758f85a..ccb385cd 100644 --- a/examples/echo/src/generated/grpc.examples.echo.rs +++ b/examples/echo/src/generated/grpc.examples.echo.rs @@ -40,16 +40,12 @@ pub mod echo_client { &mut self, request: Request, ) -> Result, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("UnaryEcho")); - let path = http::uri::PathAndQuery::from_static( - "/grpc.examples.echo.Echo/UnaryEcho", - ); + let path = http::uri::PathAndQuery::from_static("/grpc.examples.echo.Echo/UnaryEcho"); self.inner.unary(request, codec, path, invocation).await } /// ServerStreamingEcho is server side streaming. @@ -57,51 +53,51 @@ pub mod echo_client { &mut self, request: Request, ) -> Result>, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ServerStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ServerStreamingEcho", ); - self.inner.server_streaming(request, codec, path, invocation).await + self.inner + .server_streaming(request, codec, path, invocation) + .await } /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ClientStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ClientStreamingEcho", ); - self.inner.client_streaming(request, codec, path, invocation).await + self.inner + .client_streaming(request, codec, path, invocation) + .await } /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result>, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("BidirectionalStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", ); - self.inner.bidi_streaming(request, codec, path, invocation).await + self.inner + .bidi_streaming(request, codec, path, invocation) + .await } } } @@ -118,9 +114,7 @@ pub mod echo_server { request: Request, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: futures_util::Stream< - Item = Result, - > + type ServerStreamingEchoStream: futures_util::Stream> + Send + 'static; /// ServerStreamingEcho is server side streaming. @@ -134,19 +128,14 @@ pub mod echo_server { request: Request>, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: futures_util::Stream< - Item = Result, - > + type BidirectionalStreamingEchoStream: futures_util::Stream> + Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, request: Request>, - ) -> Result< - Response, - dubbo::status::Status, - >; + ) -> Result, dubbo::status::Status>; } /// Echo is the echo service. #[derive(Debug)] @@ -176,10 +165,7 @@ pub mod echo_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready( - &mut self, - _cx: &mut Context<'_>, - ) -> Poll> { + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -192,26 +178,18 @@ pub mod echo_server { } impl UnarySvc for UnaryEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; - fn call( - &mut self, - request: Request, - ) -> Self::Future { + type Future = BoxFuture, dubbo::status::Status>; + fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.0.clone(); let fut = async move { inner.unary_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server.unary(UnaryEchoServer { inner }, req).await; Ok(res) }; @@ -222,32 +200,22 @@ pub mod echo_server { struct ServerStreamingEchoServer { inner: _Inner, } - impl ServerStreamingSvc - for ServerStreamingEchoServer { + impl ServerStreamingSvc for ServerStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; - fn call( - &mut self, - request: Request, - ) -> Self::Future { + type Future = + BoxFuture, dubbo::status::Status>; + fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.server_streaming_echo(request).await - }; + let fut = async move { inner.server_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server .server_streaming(ServerStreamingEchoServer { inner }, req) .await; @@ -260,31 +228,23 @@ pub mod echo_server { struct ClientStreamingEchoServer { inner: _Inner, } - impl ClientStreamingSvc - for ClientStreamingEchoServer { + impl ClientStreamingSvc for ClientStreamingEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; + type Future = BoxFuture, dubbo::status::Status>; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.client_streaming_echo(request).await - }; + let fut = async move { inner.client_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server .client_streaming(ClientStreamingEchoServer { inner }, req) .await; @@ -297,56 +257,41 @@ pub mod echo_server { struct BidirectionalStreamingEchoServer { inner: _Inner, } - impl StreamingSvc - for BidirectionalStreamingEchoServer { + impl StreamingSvc for BidirectionalStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; + type Future = + BoxFuture, dubbo::status::Status>; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.bidirectional_streaming_echo(request).await - }; + let fut = + async move { inner.bidirectional_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server - .bidi_streaming( - BidirectionalStreamingEchoServer { - inner, - }, - req, - ) + .bidi_streaming(BidirectionalStreamingEchoServer { inner }, req) .await; Ok(res) }; Box::pin(fut) } - _ => { - Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap(), - ) - }) - } + _ => Box::pin(async move { + Ok(http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap()) + }), } } } From e696071fb98e4d16ebc4791e950d92380aac6922 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Wed, 1 Mar 2023 22:17:08 +0800 Subject: [PATCH 15/52] Ftr: add common/utils subpackage --- common/logger/src/level.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/logger/src/level.rs b/common/logger/src/level.rs index 5a081ff0..097f1058 100644 --- a/common/logger/src/level.rs +++ b/common/logger/src/level.rs @@ -25,9 +25,9 @@ impl LevelWrapper { } } -impl From for LevelWrapper { - fn from(s: String) -> Self { - match s.to_lowercase().as_str().trim() { +impl From> for LevelWrapper { + fn from(s: Option) -> Self { + match s.unwrap().to_lowercase().as_str().trim() { "error" => LevelWrapper::new(Level::ERROR), "warn" => LevelWrapper::new(Level::WARN), "info" => LevelWrapper::new(Level::INFO), From b229836127194ad5aacd7ca8d8899cad3759c7a8 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 15:26:09 +0800 Subject: [PATCH 16/52] Ftr: config api --- .github/workflows/github-actions.yml | 2 +- Cargo.toml | 3 + common/base/Cargo.toml | 2 +- common/base/src/constants.rs | 3 + common/base/src/lib.rs | 1 + common/base/src/types/alias.rs | 20 ++ common/base/src/types/mod.rs | 17 ++ common/base/src/url.rs | 2 +- common/logger/Cargo.toml | 7 +- common/logger/src/tracing_configurer.rs | 8 +- common/utils/src/lib.rs | 1 - common/utils/src/path_util.rs | 2 +- common/utils/tests/application.yaml | 4 - config/Cargo.toml | 6 +- config/src/api.rs | 16 ++ config/src/config.rs | 20 +- config/src/lib.rs | 25 ++- config/src/types/mod.rs | 21 ++ config/src/{ => types}/protocol.rs | 3 +- config/src/{ => types}/provider.rs | 0 config/src/{ => types}/registry.rs | 0 config/src/{ => types}/service.rs | 0 .../src/yaml_util.rs => config/src/util.rs | 7 +- config/tests/dubbo.yaml | 26 +++ application.yaml => dubbo.yaml | 0 dubbo/Cargo.toml | 5 +- examples/echo/Cargo.toml | 18 +- .../echo/src/generated/grpc.examples.echo.rs | 179 ++++++++++++------ examples/greeter/Cargo.toml | 2 +- 29 files changed, 292 insertions(+), 108 deletions(-) create mode 100644 common/base/src/types/alias.rs create mode 100644 common/base/src/types/mod.rs delete mode 100644 common/utils/tests/application.yaml create mode 100644 config/src/api.rs create mode 100644 config/src/types/mod.rs rename config/src/{ => types}/protocol.rs (96%) rename config/src/{ => types}/provider.rs (100%) rename config/src/{ => types}/registry.rs (100%) rename config/src/{ => types}/service.rs (100%) rename common/utils/src/yaml_util.rs => config/src/util.rs (94%) create mode 100644 config/tests/dubbo.yaml rename application.yaml => dubbo.yaml (100%) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index b02b3bc9..e8881e01 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -94,5 +94,5 @@ jobs: ../../target/debug/greeter-client env: ZOOKEEPER_SERVERS: 127.0.0.1:2181 - DUBBO_CONFIG_PATH: ./application.yaml + DUBBO_CONFIG_PATH: ./dubbo.yaml working-directory: examples/greeter diff --git a/Cargo.toml b/Cargo.toml index 1d173a38..96d187fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,9 +38,12 @@ futures = "0.3" serde = "1" serde_json = "1" urlencoding = "2.1.2" +tracing = "0.1" +tracing-subscriber = "0.3" logger = {path="./common/logger"} utils = {path="./common/utils"} base = {path="./common/base"} +config = {path="./config"} remoting-net = {path="./remoting/net"} protocol = {path= "protocol/base" } protocol-dubbo2 = {path="./protocol/dubbo2"} diff --git a/common/base/Cargo.toml b/common/base/Cargo.toml index 7397c195..9996de2c 100644 --- a/common/base/Cargo.toml +++ b/common/base/Cargo.toml @@ -8,4 +8,4 @@ edition = "2021" [dependencies] urlencoding.workspace = true http = "0.2" -logger.workspace = true \ No newline at end of file +tracing.workspace=true \ No newline at end of file diff --git a/common/base/src/constants.rs b/common/base/src/constants.rs index b1faf270..97d7f424 100644 --- a/common/base/src/constants.rs +++ b/common/base/src/constants.rs @@ -29,3 +29,6 @@ pub const INTERFACE_KEY: &str = "interface"; pub const ANYHOST_KEY: &str = "anyhost"; pub const SIDE_KEY: &str = "side"; pub const TIMESTAMP_KEY: &str = "timestamp"; + +// file name +pub const DEFAULT_CONFIG_FILE: &str = "dubbo.yaml"; diff --git a/common/base/src/lib.rs b/common/base/src/lib.rs index b97b342f..aec127c0 100644 --- a/common/base/src/lib.rs +++ b/common/base/src/lib.rs @@ -20,6 +20,7 @@ )] pub mod constants; pub mod node; +pub mod types; pub mod url; pub use node::Node; diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs new file mode 100644 index 00000000..365c4d23 --- /dev/null +++ b/common/base/src/types/alias.rs @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +// type for registryName;can be customized +pub type RegistryName = String; +// protocolKey defined in protocol layer, mean specified protocol +pub type ProtocolKey = String; diff --git a/common/base/src/types/mod.rs b/common/base/src/types/mod.rs new file mode 100644 index 00000000..8e8b88c7 --- /dev/null +++ b/common/base/src/types/mod.rs @@ -0,0 +1,17 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +pub mod alias; diff --git a/common/base/src/url.rs b/common/base/src/url.rs index 81a72c2b..64911ed4 100644 --- a/common/base/src/url.rs +++ b/common/base/src/url.rs @@ -48,7 +48,7 @@ impl Url { let uri = url .parse::() .map_err(|err| { - logger::tracing::error!("fail to parse url({}), err: {:?}", url, err); + tracing::error!("fail to parse url({}), err: {:?}", url, err); }) .unwrap(); let query = uri.path_and_query().unwrap().query(); diff --git a/common/logger/Cargo.toml b/common/logger/Cargo.toml index e965706e..354cbb15 100644 --- a/common/logger/Cargo.toml +++ b/common/logger/Cargo.toml @@ -6,7 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tracing = "0.1" -tracing-subscriber = "0.3" +tracing.workspace=true +tracing-subscriber.workspace=true once_cell.workspace = true -utils.workspace = true \ No newline at end of file +utils.workspace = true +config.workspace = true \ No newline at end of file diff --git a/common/logger/src/tracing_configurer.rs b/common/logger/src/tracing_configurer.rs index 1e2081f8..654cfa32 100644 --- a/common/logger/src/tracing_configurer.rs +++ b/common/logger/src/tracing_configurer.rs @@ -18,15 +18,17 @@ // https://github.com/tokio-rs/tracing/issues/971 use crate::level::LevelWrapper; +use config::util::yaml_key_reader; use std::path::PathBuf; use tracing::debug; -use utils::{path_util, yaml_util}; +use tracing_subscriber::util; +use utils::path_util; pub(crate) fn default() { let path_buf = PathBuf::new() .join(path_util::app_root_dir()) - .join("application.yaml"); - let level: LevelWrapper = yaml_util::yaml_key_reader(path_buf, "logging.level") + .join("../../../dubbo.yaml"); + let level: LevelWrapper = util::yaml_key_reader(path_buf, "logging.level") .unwrap() .into(); tracing_subscriber::fmt() diff --git a/common/utils/src/lib.rs b/common/utils/src/lib.rs index 7a0a45b8..de5689e5 100644 --- a/common/utils/src/lib.rs +++ b/common/utils/src/lib.rs @@ -16,4 +16,3 @@ */ pub mod host_util; pub mod path_util; -pub mod yaml_util; diff --git a/common/utils/src/path_util.rs b/common/utils/src/path_util.rs index 347f1088..f57eee89 100644 --- a/common/utils/src/path_util.rs +++ b/common/utils/src/path_util.rs @@ -32,7 +32,7 @@ mod tests { #[test] fn test_app_root_dir() { - let dir = app_root_dir().join("application.yaml"); + let dir = app_root_dir().join("../../../dubbo.yaml"); println!("dir: {}", dir.display()); } } diff --git a/common/utils/tests/application.yaml b/common/utils/tests/application.yaml deleted file mode 100644 index a40e4fe3..00000000 --- a/common/utils/tests/application.yaml +++ /dev/null @@ -1,4 +0,0 @@ -logging: - level: INFO - file: - path: /tmp/test.log diff --git a/config/Cargo.toml b/config/Cargo.toml index b4e19d47..eef16124 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "dubbo-config" +name = "config" version = "0.3.0" edition = "2021" license = "Apache-2.0" @@ -15,4 +15,6 @@ serde_yaml.workspace = true lazy_static.workspace = true once_cell.workspace = true utils.workspace = true -logger.workspace=true \ No newline at end of file +anyhow.workspace = true +base.workspace = true +tracing.workspace = true diff --git a/config/src/api.rs b/config/src/api.rs new file mode 100644 index 00000000..2944f981 --- /dev/null +++ b/config/src/api.rs @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ diff --git a/config/src/config.rs b/config/src/config.rs index f63b490c..1c02d8a0 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -17,18 +17,22 @@ use std::{collections::HashMap, env, path::PathBuf}; -use crate::{protocol::Protocol, registry::RegistryConfig}; -use logger::tracing; use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; -use utils::yaml_util::yaml_file_parser; -use super::{protocol::ProtocolConfig, provider::ProviderConfig, service::ServiceConfig}; +use base::constants::DUBBO_KEY; +use base::types::alias::RegistryName; +use logger::tracing; +use utils::util::yaml_file_parser; -pub const DUBBO_CONFIG_PATH: &str = "application.yaml"; +use crate::types::provider::ProviderConfig; +use crate::types::service::ServiceConfig; +use crate::util::yaml_file_parser; +use crate::{protocol::Protocol, registry::RegistryConfig}; + +use super::{protocol::ProtocolConfig, provider::ProviderConfig, service::ServiceConfig}; pub static GLOBAL_ROOT_CONFIG: OnceCell = OnceCell::new(); -pub const DUBBO_CONFIG_PREFIX: &str = "dubbo"; /// used to storage all structed config, from some source: cmd, file..; /// Impl Config trait, business init by read Config trait @@ -42,7 +46,7 @@ pub struct RootConfig { pub provider: ProviderConfig, #[serde(default)] - pub registries: HashMap, + pub registries: HashMap, #[serde(default)] pub data: HashMap, @@ -89,7 +93,7 @@ impl RootConfig { let conf: HashMap = yaml_file_parser(PathBuf::new().join(config_path)).unwrap(); - let root_config: RootConfig = conf.get(DUBBO_CONFIG_PREFIX).unwrap().clone(); + let root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); tracing::debug!("origin config: {:?}", conf); Ok(root_config) } diff --git a/config/src/lib.rs b/config/src/lib.rs index 0748c667..0e7376e7 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -15,10 +15,27 @@ * limitations under the License. */ +use base::constants::DEFAULT_CONFIG_FILE; pub use config::*; +use std::path::PathBuf; pub mod config; -pub mod protocol; -pub mod provider; -pub mod registry; -pub mod service; +pub use provider; +pub use service; +pub use types::protocol; +pub use types::registry; +use utils::path_util::app_root_dir; + +pub mod api; +pub mod types; +pub mod util; + +pub fn get_config_file() -> PathBuf { + PathBuf::new() + .join(app_root_dir()) + .join(DEFAULT_CONFIG_FILE) +} + +pub fn config_api() -> RootConfig { + todo!() +} diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs new file mode 100644 index 00000000..efec8c4e --- /dev/null +++ b/config/src/types/mod.rs @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +pub(crate) mod protocol; +pub(crate) mod provider; +pub(crate) mod registry; +pub(crate) mod service; diff --git a/config/src/protocol.rs b/config/src/types/protocol.rs similarity index 96% rename from config/src/protocol.rs rename to config/src/types/protocol.rs index 86ff0531..9be2ee9e 100644 --- a/config/src/protocol.rs +++ b/config/src/types/protocol.rs @@ -17,6 +17,7 @@ use std::collections::HashMap; +use base::types::alias::ProtocolKey; use serde::{Deserialize, Serialize}; pub const DEFAULT_PROTOCOL: &str = "triple"; @@ -31,7 +32,7 @@ pub struct Protocol { pub params: HashMap, } -pub type ProtocolConfig = HashMap; +pub type ProtocolConfig = HashMap; pub trait ProtocolRetrieve { fn get_protocol(&self, protocol_key: &str) -> Option; diff --git a/config/src/provider.rs b/config/src/types/provider.rs similarity index 100% rename from config/src/provider.rs rename to config/src/types/provider.rs diff --git a/config/src/registry.rs b/config/src/types/registry.rs similarity index 100% rename from config/src/registry.rs rename to config/src/types/registry.rs diff --git a/config/src/service.rs b/config/src/types/service.rs similarity index 100% rename from config/src/service.rs rename to config/src/types/service.rs diff --git a/common/utils/src/yaml_util.rs b/config/src/util.rs similarity index 94% rename from common/utils/src/yaml_util.rs rename to config/src/util.rs index f8e0adfe..ad27fe83 100644 --- a/common/utils/src/yaml_util.rs +++ b/config/src/util.rs @@ -64,10 +64,11 @@ pub fn yaml_key_reader(path: PathBuf, key: &str) -> Result, Error #[cfg(test)] mod tests { use std::collections::HashMap; + use utils::path_util::app_root_dir; use crate::{ path_util::app_root_dir, - yaml_util::{yaml_file_parser, yaml_key_reader}, + util::{yaml_file_parser, yaml_key_reader}, }; #[test] @@ -76,7 +77,7 @@ mod tests { .join("common") .join("utils") .join("tests") - .join("application.yaml"); + .join("../../dubbo.yaml"); let config = yaml_file_parser::>>(path).unwrap(); println!("{:?}", config); } @@ -87,7 +88,7 @@ mod tests { .join("common") .join("utils") .join("tests") - .join("application.yaml"); + .join("../../dubbo.yaml"); let config = yaml_key_reader(path.clone(), "logging.level").unwrap(); println!("{:?}", config); let config = yaml_key_reader(path, "logging.file.path").unwrap(); diff --git a/config/tests/dubbo.yaml b/config/tests/dubbo.yaml new file mode 100644 index 00000000..4ed15c1d --- /dev/null +++ b/config/tests/dubbo.yaml @@ -0,0 +1,26 @@ +logging: + level: INFO + file: + path: /tmp/test.log +dubbo: + protocols: + triple: + ip: 0.0.0.0 + port: '8888' + name: tri + registries: + demoZK: + protocol: zookeeper + address: 0.0.0.0:2181 + provider: + services: + GreeterProvider: + version: 1.0.0 + group: test + protocol: triple + interface: org.apache.dubbo.sample.tri.Greeter + consumer: + references: + GreeterClientImpl: + url: tri://localhost:20000 + protocol: tri \ No newline at end of file diff --git a/application.yaml b/dubbo.yaml similarity index 100% rename from application.yaml rename to dubbo.yaml diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml index 3b66523b..8874b4ce 100644 --- a/dubbo/Cargo.toml +++ b/dubbo/Cargo.toml @@ -36,9 +36,8 @@ aws-smithy-http = "0.54.1" itertools.workspace = true urlencoding.workspace = true lazy_static.workspace = true -base.workspace=true - -dubbo-config = { path = "../config", version = "0.3.0" } +base.workspace = true +config.workspace = true #对象存储 state = { version = "0.5", features = ["tls"] } diff --git a/examples/echo/Cargo.toml b/examples/echo/Cargo.toml index 53f8b9a3..5f9da75a 100644 --- a/examples/echo/Cargo.toml +++ b/examples/echo/Cargo.toml @@ -22,19 +22,19 @@ path = "src/echo/client.rs" [dependencies] http = "0.2" http-body = "0.4.4" -futures-util = {version = "0.3", default-features = false} -tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] } -prost-derive = {version = "0.10", optional = true} +futures-util = { version = "0.3", default-features = false } +tokio = { version = "1.0", features = ["rt-multi-thread", "time", "fs", "macros", "net", "signal"] } +prost-derive = { version = "0.10", optional = true } prost = "0.10.4" async-trait = "0.1.56" tokio-stream = "0.1" -logger.workspace=true +logger.workspace = true -hyper = { version = "0.14.19", features = ["full"]} +hyper = { version = "0.14.19", features = ["full"] } -dubbo = {path = "../../dubbo", version = "0.3.0" } -dubbo-config = {path = "../../config", version = "0.3.0" } -registry-zookeeper.workspace=true +dubbo = { path = "../../dubbo", version = "0.3.0" } +config.workspace = true +registry-zookeeper.workspace = true [build-dependencies] -dubbo-build = {path = "../../dubbo-build", version = "0.3.0" } +dubbo-build = { path = "../../dubbo-build", version = "0.3.0" } diff --git a/examples/echo/src/generated/grpc.examples.echo.rs b/examples/echo/src/generated/grpc.examples.echo.rs index ccb385cd..8758f85a 100644 --- a/examples/echo/src/generated/grpc.examples.echo.rs +++ b/examples/echo/src/generated/grpc.examples.echo.rs @@ -40,12 +40,16 @@ pub mod echo_client { &mut self, request: Request, ) -> Result, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("UnaryEcho")); - let path = http::uri::PathAndQuery::from_static("/grpc.examples.echo.Echo/UnaryEcho"); + let path = http::uri::PathAndQuery::from_static( + "/grpc.examples.echo.Echo/UnaryEcho", + ); self.inner.unary(request, codec, path, invocation).await } /// ServerStreamingEcho is server side streaming. @@ -53,51 +57,51 @@ pub mod echo_client { &mut self, request: Request, ) -> Result>, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ServerStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ServerStreamingEcho", ); - self.inner - .server_streaming(request, codec, path, invocation) - .await + self.inner.server_streaming(request, codec, path, invocation).await } /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ClientStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ClientStreamingEcho", ); - self.inner - .client_streaming(request, codec, path, invocation) - .await + self.inner.client_streaming(request, codec, path, invocation).await } /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result>, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("BidirectionalStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", ); - self.inner - .bidi_streaming(request, codec, path, invocation) - .await + self.inner.bidi_streaming(request, codec, path, invocation).await } } } @@ -114,7 +118,9 @@ pub mod echo_server { request: Request, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: futures_util::Stream> + type ServerStreamingEchoStream: futures_util::Stream< + Item = Result, + > + Send + 'static; /// ServerStreamingEcho is server side streaming. @@ -128,14 +134,19 @@ pub mod echo_server { request: Request>, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: futures_util::Stream> + type BidirectionalStreamingEchoStream: futures_util::Stream< + Item = Result, + > + Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, request: Request>, - ) -> Result, dubbo::status::Status>; + ) -> Result< + Response, + dubbo::status::Status, + >; } /// Echo is the echo service. #[derive(Debug)] @@ -165,7 +176,10 @@ pub mod echo_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -178,18 +192,26 @@ pub mod echo_server { } impl UnarySvc for UnaryEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture, dubbo::status::Status>; - fn call(&mut self, request: Request) -> Self::Future { + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; + fn call( + &mut self, + request: Request, + ) -> Self::Future { let inner = self.inner.0.clone(); let fut = async move { inner.unary_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server.unary(UnaryEchoServer { inner }, req).await; Ok(res) }; @@ -200,22 +222,32 @@ pub mod echo_server { struct ServerStreamingEchoServer { inner: _Inner, } - impl ServerStreamingSvc for ServerStreamingEchoServer { + impl ServerStreamingSvc + for ServerStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; - type Future = - BoxFuture, dubbo::status::Status>; - fn call(&mut self, request: Request) -> Self::Future { + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; + fn call( + &mut self, + request: Request, + ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { inner.server_streaming_echo(request).await }; + let fut = async move { + inner.server_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server .server_streaming(ServerStreamingEchoServer { inner }, req) .await; @@ -228,23 +260,31 @@ pub mod echo_server { struct ClientStreamingEchoServer { inner: _Inner, } - impl ClientStreamingSvc for ClientStreamingEchoServer { + impl ClientStreamingSvc + for ClientStreamingEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture, dubbo::status::Status>; + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { inner.client_streaming_echo(request).await }; + let fut = async move { + inner.client_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server .client_streaming(ClientStreamingEchoServer { inner }, req) .await; @@ -257,41 +297,56 @@ pub mod echo_server { struct BidirectionalStreamingEchoServer { inner: _Inner, } - impl StreamingSvc for BidirectionalStreamingEchoServer { + impl StreamingSvc + for BidirectionalStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; - type Future = - BoxFuture, dubbo::status::Status>; + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = - async move { inner.bidirectional_streaming_echo(request).await }; + let fut = async move { + inner.bidirectional_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server - .bidi_streaming(BidirectionalStreamingEchoServer { inner }, req) + .bidi_streaming( + BidirectionalStreamingEchoServer { + inner, + }, + req, + ) .await; Ok(res) }; Box::pin(fut) } - _ => Box::pin(async move { - Ok(http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap()) - }), + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } } } } diff --git a/examples/greeter/Cargo.toml b/examples/greeter/Cargo.toml index a8c6cacf..8a9925bb 100644 --- a/examples/greeter/Cargo.toml +++ b/examples/greeter/Cargo.toml @@ -30,7 +30,7 @@ async-trait = "0.1.56" tokio-stream = "0.1" logger = { path = "../../common/logger" } dubbo = { path = "../../dubbo", version = "0.3.0" } -dubbo-config = { path = "../../config", version = "0.3.0" } +config.workspace = true registry-zookeeper.workspace = true registry-nacos.workspace = true base.workspace = true From 71fe285f32965383e910c2a2cbd437b7f3edf66d Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 15:54:53 +0800 Subject: [PATCH 17/52] Ftr: config api --- common/base/src/constants.rs | 5 +++++ common/utils/Cargo.toml | 2 +- common/utils/src/env_util.rs | 24 ++++++++++++++++++++++++ common/utils/src/lib.rs | 1 + config/src/config.rs | 33 +++++---------------------------- config/src/lib.rs | 24 ++++++++++++++++-------- config/src/util.rs | 5 +---- 7 files changed, 53 insertions(+), 41 deletions(-) create mode 100644 common/utils/src/env_util.rs diff --git a/common/base/src/constants.rs b/common/base/src/constants.rs index 97d7f424..ee2876b2 100644 --- a/common/base/src/constants.rs +++ b/common/base/src/constants.rs @@ -32,3 +32,8 @@ pub const TIMESTAMP_KEY: &str = "timestamp"; // file name pub const DEFAULT_CONFIG_FILE: &str = "dubbo.yaml"; + +// env keys + +pub const ENV_DUBBO_CONFIG_PATH: &str = "DUBBO_CONFIG_PATH"; +pub const ENV_DUBBO_CONFIG_FILE: &str = "DUBBO_CONFIG_FILE"; diff --git a/common/utils/Cargo.toml b/common/utils/Cargo.toml index 0b8c84f1..df4519f5 100644 --- a/common/utils/Cargo.toml +++ b/common/utils/Cargo.toml @@ -12,4 +12,4 @@ project-root = "0.2.2" anyhow.workspace=true once_cell.workspace = true local-ip-address = "0.5.1" -port-selector = "0.1.6" \ No newline at end of file +port-selector = "0.1.6" diff --git a/common/utils/src/env_util.rs b/common/utils/src/env_util.rs new file mode 100644 index 00000000..d6c8678a --- /dev/null +++ b/common/utils/src/env_util.rs @@ -0,0 +1,24 @@ +use std::env; + +pub fn get_env_value(env_key: &str) -> Option { + env::var(env_key).ok() +} + +pub fn get_env_value_for_i32(env_key: &str) -> Option { + get_env_value(env_key).map(|v| v.parse::().unwrap()) +} + +#[cfg(test)] +mod tests { + use crate::env_util::{get_env_value, get_env_value_for_i32}; + use std::env; + + #[test] + fn test_get_env_value() { + env::set_var("TEST_ENV", "testxxx1"); + env::set_var("TEST_ENV3", "999"); + assert!(get_env_value("TEST_ENV").is_some()); + assert!(get_env_value("TEST_ENV2").is_none()); + assert_eq!(get_env_value_for_i32("TEST_ENV3"), Some(999_i32)) + } +} diff --git a/common/utils/src/lib.rs b/common/utils/src/lib.rs index de5689e5..72e665dc 100644 --- a/common/utils/src/lib.rs +++ b/common/utils/src/lib.rs @@ -14,5 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +pub mod env_util; pub mod host_util; pub mod path_util; diff --git a/config/src/config.rs b/config/src/config.rs index 1c02d8a0..5bad0603 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -15,22 +15,20 @@ * limitations under the License. */ -use std::{collections::HashMap, env, path::PathBuf}; +use std::{collections::HashMap, env}; use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; +use crate::get_config_file; use base::constants::DUBBO_KEY; use base::types::alias::RegistryName; -use logger::tracing; -use utils::util::yaml_file_parser; +use crate::types::protocol::{Protocol, ProtocolConfig}; use crate::types::provider::ProviderConfig; +use crate::types::registry::RegistryConfig; use crate::types::service::ServiceConfig; use crate::util::yaml_file_parser; -use crate::{protocol::Protocol, registry::RegistryConfig}; - -use super::{protocol::ProtocolConfig, provider::ProviderConfig, service::ServiceConfig}; pub static GLOBAL_ROOT_CONFIG: OnceCell = OnceCell::new(); @@ -72,27 +70,7 @@ impl RootConfig { } pub fn load(&self) -> std::io::Result { - let config_path = match env::var("DUBBO_CONFIG_PATH") { - Ok(v) => { - tracing::info!("read config_path from env: {:?}", v); - v - } - Err(err) => { - tracing::warn!( - "error loading config_path: {:?}, use default path: {:?}", - err, - DUBBO_CONFIG_PATH - ); - utils::path_util::app_root_dir() - .join(DUBBO_CONFIG_PATH) - .to_str() - .unwrap() - .to_string() - } - }; - - let conf: HashMap = - yaml_file_parser(PathBuf::new().join(config_path)).unwrap(); + let conf: HashMap = yaml_file_parser(get_config_file()).unwrap(); let root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); tracing::debug!("origin config: {:?}", conf); Ok(root_config) @@ -188,7 +166,6 @@ mod tests { #[test] fn test_load() { - logger::init(); let r = RootConfig::new(); let r = r.load().unwrap(); println!("{:#?}", r); diff --git a/config/src/lib.rs b/config/src/lib.rs index 0e7376e7..04c534ce 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -15,25 +15,33 @@ * limitations under the License. */ -use base::constants::DEFAULT_CONFIG_FILE; +use base::constants::{DEFAULT_CONFIG_FILE, ENV_DUBBO_CONFIG_FILE, ENV_DUBBO_CONFIG_PATH}; pub use config::*; use std::path::PathBuf; +use utils::env_util::get_env_value; pub mod config; -pub use provider; -pub use service; -pub use types::protocol; -pub use types::registry; + use utils::path_util::app_root_dir; pub mod api; pub mod types; pub mod util; +// resolve yaml config file pub fn get_config_file() -> PathBuf { - PathBuf::new() - .join(app_root_dir()) - .join(DEFAULT_CONFIG_FILE) + let mut path_buf = PathBuf::new(); + if get_env_value(ENV_DUBBO_CONFIG_PATH).is_some() { + path_buf = path_buf.join(get_env_value(ENV_DUBBO_CONFIG_PATH).unwrap()); + } else { + path_buf = path_buf.join(app_root_dir()); + } + if get_env_value(ENV_DUBBO_CONFIG_FILE).is_some() { + path_buf = path_buf.join(get_env_value(ENV_DUBBO_CONFIG_FILE).unwrap()); + } else { + path_buf = path_buf.join(DEFAULT_CONFIG_FILE); + } + path_buf } pub fn config_api() -> RootConfig { diff --git a/config/src/util.rs b/config/src/util.rs index ad27fe83..dcc5bacc 100644 --- a/config/src/util.rs +++ b/config/src/util.rs @@ -66,10 +66,7 @@ mod tests { use std::collections::HashMap; use utils::path_util::app_root_dir; - use crate::{ - path_util::app_root_dir, - util::{yaml_file_parser, yaml_key_reader}, - }; + use crate::util::{yaml_file_parser, yaml_key_reader}; #[test] fn test_yaml_file_parser() { From de8c0164677fc25464709749a9117f70b92f3b86 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 15:57:35 +0800 Subject: [PATCH 18/52] Ftr: config api --- config/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/src/lib.rs b/config/src/lib.rs index 04c534ce..db405cd3 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -31,11 +31,13 @@ pub mod util; // resolve yaml config file pub fn get_config_file() -> PathBuf { let mut path_buf = PathBuf::new(); + // resolve config path if get_env_value(ENV_DUBBO_CONFIG_PATH).is_some() { path_buf = path_buf.join(get_env_value(ENV_DUBBO_CONFIG_PATH).unwrap()); } else { path_buf = path_buf.join(app_root_dir()); } + // resolve config filename if get_env_value(ENV_DUBBO_CONFIG_FILE).is_some() { path_buf = path_buf.join(get_env_value(ENV_DUBBO_CONFIG_FILE).unwrap()); } else { From ab95b3b08be27888b4287a833a68b107e34ada5b Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 16:05:58 +0800 Subject: [PATCH 19/52] Ftr: config api --- config/src/api.rs | 4 ++++ config/src/lib.rs | 28 ++-------------------------- config/src/location.rs | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 26 deletions(-) create mode 100644 config/src/location.rs diff --git a/config/src/api.rs b/config/src/api.rs index 2944f981..ceb84cde 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -14,3 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +pub fn set_property_with_key_path(key: &str, value: &str) { + todo!() +} diff --git a/config/src/lib.rs b/config/src/lib.rs index db405cd3..1ebb90c2 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -15,37 +15,13 @@ * limitations under the License. */ -use base::constants::{DEFAULT_CONFIG_FILE, ENV_DUBBO_CONFIG_FILE, ENV_DUBBO_CONFIG_PATH}; pub use config::*; -use std::path::PathBuf; -use utils::env_util::get_env_value; pub mod config; -use utils::path_util::app_root_dir; - pub mod api; +pub mod location; pub mod types; pub mod util; -// resolve yaml config file -pub fn get_config_file() -> PathBuf { - let mut path_buf = PathBuf::new(); - // resolve config path - if get_env_value(ENV_DUBBO_CONFIG_PATH).is_some() { - path_buf = path_buf.join(get_env_value(ENV_DUBBO_CONFIG_PATH).unwrap()); - } else { - path_buf = path_buf.join(app_root_dir()); - } - // resolve config filename - if get_env_value(ENV_DUBBO_CONFIG_FILE).is_some() { - path_buf = path_buf.join(get_env_value(ENV_DUBBO_CONFIG_FILE).unwrap()); - } else { - path_buf = path_buf.join(DEFAULT_CONFIG_FILE); - } - path_buf -} - -pub fn config_api() -> RootConfig { - todo!() -} +pub use location::get_config_file; diff --git a/config/src/location.rs b/config/src/location.rs new file mode 100644 index 00000000..8c22aad5 --- /dev/null +++ b/config/src/location.rs @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +use base::constants::{DEFAULT_CONFIG_FILE, ENV_DUBBO_CONFIG_FILE, ENV_DUBBO_CONFIG_PATH}; +use std::path::PathBuf; +use utils::env_util::get_env_value; +use utils::path_util::app_root_dir; + +// resolve yaml config file +pub fn get_config_file() -> PathBuf { + let mut path_buf = PathBuf::new(); + // resolve config path + if get_env_value(ENV_DUBBO_CONFIG_PATH).is_some() { + path_buf = path_buf.join(get_env_value(ENV_DUBBO_CONFIG_PATH).unwrap()); + } else { + path_buf = path_buf.join(app_root_dir()); + } + // resolve config filename + if get_env_value(ENV_DUBBO_CONFIG_FILE).is_some() { + path_buf = path_buf.join(get_env_value(ENV_DUBBO_CONFIG_FILE).unwrap()); + } else { + path_buf = path_buf.join(DEFAULT_CONFIG_FILE); + } + path_buf +} From 01ce2dd791e55f8294056b04635edea03fb923e2 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 16:13:34 +0800 Subject: [PATCH 20/52] Ftr: config api --- common/base/src/types/alias.rs | 3 +++ common/base/src/url.rs | 5 +++-- config/src/types/provider.rs | 5 +++-- config/src/types/registry.rs | 3 ++- config/src/types/service.rs | 5 +++-- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs index 365c4d23..71b10127 100644 --- a/common/base/src/types/alias.rs +++ b/common/base/src/types/alias.rs @@ -18,3 +18,6 @@ pub type RegistryName = String; // protocolKey defined in protocol layer, mean specified protocol pub type ProtocolKey = String; +pub type ServiceName = String; + +pub type ServiceKey = String; diff --git a/common/base/src/url.rs b/common/base/src/url.rs index 64911ed4..0c52561f 100644 --- a/common/base/src/url.rs +++ b/common/base/src/url.rs @@ -21,6 +21,7 @@ use std::{ }; use crate::constants::{GROUP_KEY, INTERFACE_KEY, VERSION_KEY}; +use crate::types::alias::{ProtocolKey, ServiceKey, ServiceName}; use http::Uri; #[derive(Debug, Clone, Default, PartialEq)] @@ -70,11 +71,11 @@ impl Url { Some(url_inst) } - pub fn get_service_key(&self) -> String { + pub fn get_service_key(&self) -> ServiceKey { self.service_key.clone() } - pub fn get_service_name(&self) -> String { + pub fn get_service_name(&self) -> ServiceName { self.service_name.clone() } diff --git a/config/src/types/provider.rs b/config/src/types/provider.rs index ccb9cf8b..d21b1531 100644 --- a/config/src/types/provider.rs +++ b/config/src/types/provider.rs @@ -17,6 +17,7 @@ use std::collections::HashMap; +use base::types::alias::ServiceName; use serde::{Deserialize, Serialize}; use super::service::ServiceConfig; @@ -28,7 +29,7 @@ pub struct ProviderConfig { #[serde(default)] pub protocol_ids: Vec, #[serde(default)] - pub services: HashMap, + pub services: HashMap, } impl ProviderConfig { @@ -50,7 +51,7 @@ impl ProviderConfig { self } - pub fn with_services(mut self, services: HashMap) -> Self { + pub fn with_services(mut self, services: HashMap) -> Self { self.services = services; self } diff --git a/config/src/types/registry.rs b/config/src/types/registry.rs index c2348b07..5e823f76 100644 --- a/config/src/types/registry.rs +++ b/config/src/types/registry.rs @@ -14,12 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use base::types::alias::ProtocolKey; use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct RegistryConfig { #[serde(default)] - pub protocol: String, + pub protocol: ProtocolKey, #[serde(default)] pub address: String, } diff --git a/config/src/types/service.rs b/config/src/types/service.rs index 1f85a926..76e59cea 100644 --- a/config/src/types/service.rs +++ b/config/src/types/service.rs @@ -15,13 +15,14 @@ * limitations under the License. */ +use base::types::alias::ProtocolKey; use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct ServiceConfig { pub version: String, pub group: String, - pub protocol: String, + pub protocol: ProtocolKey, pub interface: String, } @@ -38,7 +39,7 @@ impl ServiceConfig { Self { group, ..self } } - pub fn protocol(self, protocol: String) -> Self { + pub fn protocol(self, protocol: ProtocolKey) -> Self { Self { protocol, ..self } } From 46e01fe248ebc8982acd1272ea230ac6eab45f0f Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 17:22:33 +0800 Subject: [PATCH 21/52] Ftr: config api --- common/base/src/types/alias.rs | 7 ++-- config/src/config.rs | 60 ---------------------------------- 2 files changed, 4 insertions(+), 63 deletions(-) diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs index 71b10127..6da9bb41 100644 --- a/common/base/src/types/alias.rs +++ b/common/base/src/types/alias.rs @@ -14,10 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// type for registryName;can be customized +// type for registryName;can be customized;RegistryKey eg. zookeeper/nacos/consul pub type RegistryName = String; +pub type RegistryKey = String; // protocolKey defined in protocol layer, mean specified protocol -pub type ProtocolKey = String; pub type ServiceName = String; - pub type ServiceKey = String; +// +pub type ProtocolKey = String; diff --git a/config/src/config.rs b/config/src/config.rs index 5bad0603..2d6ecf79 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -45,9 +45,6 @@ pub struct RootConfig { #[serde(default)] pub registries: HashMap, - - #[serde(default)] - pub data: HashMap, } pub fn get_global_config() -> &'static RootConfig { @@ -65,7 +62,6 @@ impl RootConfig { protocols: HashMap::new(), registries: HashMap::new(), provider: ProviderConfig::new(), - data: HashMap::new(), } } @@ -108,12 +104,6 @@ impl RootConfig { self.provider = provider.clone(); println!("provider config: {:?}", provider); - // 通过环境变量读取某个文件。加在到内存中 - self.data.insert( - "dubbo.provider.url".to_string(), - "dubbo://127.0.0.1:8888/?serviceName=hellworld".to_string(), - ); - // self.data.insert("dubbo.consume.", v) } #[inline] @@ -121,53 +111,3 @@ impl RootConfig { Box::leak(Box::new(self)) } } - -impl Config for RootConfig { - fn bool(&self, key: String) -> bool { - match self.data.get(&key) { - None => false, - Some(val) => match val.parse::() { - Ok(v) => v, - Err(_err) => { - tracing::error!("key: {}, val: {} is not boolean", key, val); - false - } - }, - } - } - - fn string(&self, key: String) -> String { - match self.data.get(&key) { - None => "".to_string(), - Some(val) => val.to_string(), - } - } -} - -pub trait BusinessConfig { - fn init() -> Self; - fn load() -> Result<(), std::convert::Infallible>; -} - -pub trait Config { - fn bool(&self, key: String) -> bool; - fn string(&self, key: String) -> String; -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_config() { - let mut r = RootConfig::new(); - r.test_config(); - } - - #[test] - fn test_load() { - let r = RootConfig::new(); - let r = r.load().unwrap(); - println!("{:#?}", r); - } -} From a81f09845509042a8362061da9bf7b80ef4dece6 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 19:31:13 +0800 Subject: [PATCH 22/52] Ftr: config api --- common/base/src/types/alias.rs | 12 ++- config/Cargo.toml | 1 + config/src/config.rs | 113 -------------------- config/src/lib.rs | 52 ++++++++- config/src/location.rs | 2 +- config/src/types/consumer.rs | 54 ++++++++++ config/src/types/mod.rs | 9 +- config/src/types/protocol.rs | 8 +- config/src/types/registry.rs | 16 ++- config/tests/dubbo.yaml | 32 ++++-- config/tests/test_api.rs | 27 +++++ config/{src/api.rs => tests/test_config.rs} | 4 - dubbo/src/framework.rs | 4 +- dubbo/src/triple/transport/service.rs | 2 +- 14 files changed, 191 insertions(+), 145 deletions(-) delete mode 100644 config/src/config.rs create mode 100644 config/src/types/consumer.rs create mode 100644 config/tests/test_api.rs rename config/{src/api.rs => tests/test_config.rs} (91%) diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs index 6da9bb41..46ab4e40 100644 --- a/common/base/src/types/alias.rs +++ b/common/base/src/types/alias.rs @@ -15,10 +15,20 @@ * limitations under the License. */ // type for registryName;can be customized;RegistryKey eg. zookeeper/nacos/consul -pub type RegistryName = String; +pub type RegistryId = String; pub type RegistryKey = String; +// service/application +pub type RegistryType = String; // protocolKey defined in protocol layer, mean specified protocol pub type ServiceName = String; pub type ServiceKey = String; // pub type ProtocolKey = String; +pub type GroupId = String; +pub type Version = String; + +pub type InterfaceName = String; + +pub type ClusterStrategy = String; + +pub type ParamKey = String; diff --git a/config/Cargo.toml b/config/Cargo.toml index eef16124..147f4f95 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -18,3 +18,4 @@ utils.workspace = true anyhow.workspace = true base.workspace = true tracing.workspace = true +tokio.workspace = true \ No newline at end of file diff --git a/config/src/config.rs b/config/src/config.rs deleted file mode 100644 index 2d6ecf79..00000000 --- a/config/src/config.rs +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -use std::{collections::HashMap, env}; - -use once_cell::sync::OnceCell; -use serde::{Deserialize, Serialize}; - -use crate::get_config_file; -use base::constants::DUBBO_KEY; -use base::types::alias::RegistryName; - -use crate::types::protocol::{Protocol, ProtocolConfig}; -use crate::types::provider::ProviderConfig; -use crate::types::registry::RegistryConfig; -use crate::types::service::ServiceConfig; -use crate::util::yaml_file_parser; - -pub static GLOBAL_ROOT_CONFIG: OnceCell = OnceCell::new(); - -/// used to storage all structed config, from some source: cmd, file..; -/// Impl Config trait, business init by read Config trait -#[allow(dead_code)] -#[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct RootConfig { - #[serde(default)] - pub protocols: ProtocolConfig, - - #[serde(default)] - pub provider: ProviderConfig, - - #[serde(default)] - pub registries: HashMap, -} - -pub fn get_global_config() -> &'static RootConfig { - GLOBAL_ROOT_CONFIG.get_or_init(|| { - tracing::debug!("current path: {:?}", env::current_dir()); - RootConfig::new() - .load() - .unwrap_or_else(|err| panic!("Failed to load global config, error: {}", err)) - }) -} - -impl RootConfig { - pub fn new() -> Self { - Self { - protocols: HashMap::new(), - registries: HashMap::new(), - provider: ProviderConfig::new(), - } - } - - pub fn load(&self) -> std::io::Result { - let conf: HashMap = yaml_file_parser(get_config_file()).unwrap(); - let root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); - tracing::debug!("origin config: {:?}", conf); - Ok(root_config) - } - - pub fn test_config(&mut self) { - let mut provider = ProviderConfig::new(); - provider.protocol_ids = vec!["triple".to_string()]; - provider.registry_ids = vec![]; - - let service_config = ServiceConfig::default() - .group("test".to_string()) - .version("1.0.0".to_string()) - .protocol("triple".to_string()) - .interface("grpc.examples.echo.Echo".to_string()); - - self.provider - .services - .insert("grpc.examples.echo.Echo".to_string(), service_config); - self.provider.services.insert( - "helloworld.Greeter".to_string(), - ServiceConfig::default() - .group("test".to_string()) - .version("1.0.0".to_string()) - .interface("helloworld.Greeter".to_string()) - .protocol("triple".to_string()), - ); - self.protocols.insert( - "triple".to_string(), - Protocol::default() - .name("triple".to_string()) - .ip("0.0.0.0".to_string()) - .port("8889".to_string()), - ); - - self.provider = provider.clone(); - println!("provider config: {:?}", provider); - } - - #[inline] - pub fn leak(self) -> &'static Self { - Box::leak(Box::new(self)) - } -} diff --git a/config/src/lib.rs b/config/src/lib.rs index 1ebb90c2..678efb92 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -15,13 +15,55 @@ * limitations under the License. */ -pub use config::*; +use base::constants::DUBBO_KEY; +use base::types::alias::RegistryId; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::sync::Arc; +use tokio::sync::Mutex; -pub mod config; - -pub mod api; pub mod location; pub mod types; pub mod util; -pub use location::get_config_file; +use crate::types::consumer::ConsumerConfig; +use crate::types::protocol::ProtocolConfig; +use crate::types::provider::ProviderConfig; +use crate::types::registry::RegistryConfig; +use crate::util::yaml_file_parser; +pub use location::get_config_location; + +pub type ConfigWrapper = Arc>; + +static GLOBAL_ROOT_CONFIG: Lazy = + Lazy::new(|| Arc::new(Mutex::new(RootConfig::default()))); + +/// used to storage all structed config, from some source: cmd, file..; +/// Impl Config trait, business init by read Config trait +#[allow(dead_code)] +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct RootConfig { + #[serde(default)] + pub protocols: ProtocolConfig, + + #[serde(default)] + pub provider: ProviderConfig, + + #[serde(default)] + pub registries: HashMap, + + pub consumers: HashMap, +} + +impl Default for RootConfig { + fn default() -> RootConfig { + let conf: HashMap = yaml_file_parser(get_config_location()).unwrap(); + let root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); + root_config + } +} + +pub fn get_root_config() -> ConfigWrapper { + GLOBAL_ROOT_CONFIG.clone() +} diff --git a/config/src/location.rs b/config/src/location.rs index 8c22aad5..cffbaeed 100644 --- a/config/src/location.rs +++ b/config/src/location.rs @@ -21,7 +21,7 @@ use utils::env_util::get_env_value; use utils::path_util::app_root_dir; // resolve yaml config file -pub fn get_config_file() -> PathBuf { +pub fn get_config_location() -> PathBuf { let mut path_buf = PathBuf::new(); // resolve config path if get_env_value(ENV_DUBBO_CONFIG_PATH).is_some() { diff --git a/config/src/types/consumer.rs b/config/src/types/consumer.rs new file mode 100644 index 00000000..411add07 --- /dev/null +++ b/config/src/types/consumer.rs @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +use std::collections::HashMap; + +use serde::Deserialize; +use serde::Serialize; + +use base::types::alias::{ + ClusterStrategy, GroupId, InterfaceName, ParamKey, ProtocolKey, RegistryId, ServiceName, +}; + +#[derive(Debug, Default, Serialize, Deserialize, Clone)] +pub struct ConsumerConfig { + #[serde(default)] + pub registry_ids: Vec, + #[serde(default)] + pub protocol_ids: Vec, + #[serde(default)] + pub references: HashMap, +} +#[derive(Debug, Default, Serialize, Deserialize, Clone)] +pub struct ReferenceConfig { + #[serde(default)] + pub url: String, + #[serde(default)] + pub protocol: ProtocolKey, + #[serde(default)] + pub group: GroupId, + #[serde(default)] + pub interface_name: InterfaceName, + #[serde(default)] + pub registry_ids: Vec, + #[serde(default)] + pub cluster: ClusterStrategy, + #[serde(default)] + pub params: HashMap, + #[serde(default)] + pub retries: u8, +} diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index efec8c4e..ab38fa9c 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -15,7 +15,8 @@ * limitations under the License. */ -pub(crate) mod protocol; -pub(crate) mod provider; -pub(crate) mod registry; -pub(crate) mod service; +pub mod consumer; +pub mod protocol; +pub mod provider; +pub mod registry; +pub mod service; diff --git a/config/src/types/protocol.rs b/config/src/types/protocol.rs index 9be2ee9e..54f893c1 100644 --- a/config/src/types/protocol.rs +++ b/config/src/types/protocol.rs @@ -17,19 +17,17 @@ use std::collections::HashMap; -use base::types::alias::ProtocolKey; +use base::types::alias::{ParamKey, ProtocolKey}; use serde::{Deserialize, Serialize}; -pub const DEFAULT_PROTOCOL: &str = "triple"; - #[derive(Default, Debug, Clone, Serialize, Deserialize)] pub struct Protocol { pub ip: String, pub port: String, - pub name: String, + pub name: ProtocolKey, #[serde(skip_serializing, skip_deserializing)] - pub params: HashMap, + pub params: HashMap, } pub type ProtocolConfig = HashMap; diff --git a/config/src/types/registry.rs b/config/src/types/registry.rs index 5e823f76..93a6f254 100644 --- a/config/src/types/registry.rs +++ b/config/src/types/registry.rs @@ -14,13 +14,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use base::types::alias::ProtocolKey; +use base::types::alias::{ParamKey, RegistryId, RegistryType}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::time::Duration; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct RegistryConfig { #[serde(default)] - pub protocol: ProtocolKey, + pub protocol: RegistryId, + #[serde(default)] + pub timeout: Duration, #[serde(default)] pub address: String, + #[serde(default)] + pub username: String, + #[serde(default)] + pub password: String, + #[serde(default)] + pub params: HashMap, + #[serde(default)] + pub registry_type: RegistryType, } diff --git a/config/tests/dubbo.yaml b/config/tests/dubbo.yaml index 4ed15c1d..a28e1d9b 100644 --- a/config/tests/dubbo.yaml +++ b/config/tests/dubbo.yaml @@ -6,21 +6,39 @@ dubbo: protocols: triple: ip: 0.0.0.0 - port: '8888' + port: 8888 name: tri registries: demoZK: protocol: zookeeper address: 0.0.0.0:2181 provider: + registry-ids: zk services: - GreeterProvider: - version: 1.0.0 - group: test - protocol: triple - interface: org.apache.dubbo.sample.tri.Greeter + UserProvider: + serialization: hessian2 + interface: org.apache.dubbo.samples.UserProvider + UserProviderTriple: + serialization: hessian2 + interface: org.apache.dubbo.samples.UserProviderTriple consumer: + filter: tracing + registry-ids: + - demoZK references: GreeterClientImpl: url: tri://localhost:20000 - protocol: tri \ No newline at end of file + protocol: tri + retries: 5 + services: + "UserProvider": + registry-ids: "demoZk" + protocol: "dubbo" + interface: "org.apache.dubbo.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" \ No newline at end of file diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs new file mode 100644 index 00000000..61cb9e10 --- /dev/null +++ b/config/tests/test_api.rs @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +#[cfg(test)] +mod tests_api { + use config::get_root_config; + + #[test] + fn test_api_overwrite_yaml() { + let root_config = get_root_config(); + println!("{:?}", root_config); + } +} diff --git a/config/src/api.rs b/config/tests/test_config.rs similarity index 91% rename from config/src/api.rs rename to config/tests/test_config.rs index ceb84cde..2944f981 100644 --- a/config/src/api.rs +++ b/config/tests/test_config.rs @@ -14,7 +14,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -pub fn set_property_with_key_path(key: &str, value: &str) { - todo!() -} diff --git a/dubbo/src/framework.rs b/dubbo/src/framework.rs index 546e2d0f..8a697bcb 100644 --- a/dubbo/src/framework.rs +++ b/dubbo/src/framework.rs @@ -34,7 +34,7 @@ use crate::{ BoxRegistry, Registry, }, }; -use dubbo_config::{get_global_config, protocol::ProtocolRetrieve, RootConfig}; +use dubbo_config::{get_root_config, protocol::ProtocolRetrieve, RootConfig}; // Invoker是否可以基于hyper写一个通用的 @@ -74,7 +74,7 @@ impl Dubbo { pub fn init(&mut self) -> Result<(), Box> { if self.config.is_none() { - self.config = Some(get_global_config()) + self.config = Some(get_root_config()) } let root_config = self.config.as_ref().unwrap(); diff --git a/dubbo/src/triple/transport/service.rs b/dubbo/src/triple/transport/service.rs index 9698276d..0644823a 100644 --- a/dubbo/src/triple/transport/service.rs +++ b/dubbo/src/triple/transport/service.rs @@ -193,7 +193,7 @@ impl DubboServer { // impl BusinessConfig for DubboServer { // fn init() -> Self { -// let conf = config::get_global_config(); +// let conf = config::get_root_config(); // DubboServer::new().with_accpet_http1(conf.bool("dubbo.server.accept_http2".to_string())) // } From fd3b053ef719a9503d189cbd7186962eb33eaba0 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 20:24:03 +0800 Subject: [PATCH 23/52] Ftr: config api --- Cargo.toml | 2 ++ common/base/src/types/alias.rs | 2 +- config/Cargo.toml | 4 +++- config/src/lib.rs | 19 +++++++++++---- config/src/location.rs | 4 ++++ config/src/types/consumer.rs | 7 ++++-- config/src/types/provider.rs | 6 +---- config/src/types/service.rs | 42 +++++++--------------------------- config/src/util.rs | 22 +++++++++++++++++- config/tests/dubbo.yaml | 2 +- config/tests/test_api.rs | 25 +++++++++++++++++++- 11 files changed, 84 insertions(+), 51 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 96d187fc..6f9f29ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,5 +56,7 @@ bb8 = "0.8.0" # A connecton pool based on tokio serde_yaml = "0.9.4" # yaml file parser once_cell = "1.16.0" itertools = "0.10.1" +ctor = "0.1.23" +getset = "0.1.2" diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs index 46ab4e40..c49ede63 100644 --- a/common/base/src/types/alias.rs +++ b/common/base/src/types/alias.rs @@ -30,5 +30,5 @@ pub type Version = String; pub type InterfaceName = String; pub type ClusterStrategy = String; - +pub type FilterKey = String; pub type ParamKey = String; diff --git a/config/Cargo.toml b/config/Cargo.toml index 147f4f95..3495cb77 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -18,4 +18,6 @@ utils.workspace = true anyhow.workspace = true base.workspace = true tracing.workspace = true -tokio.workspace = true \ No newline at end of file +tokio.workspace = true +[dev-dependencies] +ctor.workspace = true \ No newline at end of file diff --git a/config/src/lib.rs b/config/src/lib.rs index 678efb92..ab89dc34 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -16,12 +16,12 @@ */ use base::constants::DUBBO_KEY; -use base::types::alias::RegistryId; +use base::types::alias::{RegistryId, ServiceName}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use std::sync::Arc; -use tokio::sync::Mutex; +use std::path::PathBuf; +use std::sync::{Arc, Mutex}; pub mod location; pub mod types; @@ -31,6 +31,7 @@ use crate::types::consumer::ConsumerConfig; use crate::types::protocol::ProtocolConfig; use crate::types::provider::ProviderConfig; use crate::types::registry::RegistryConfig; +use crate::types::service::ServiceConfig; use crate::util::yaml_file_parser; pub use location::get_config_location; @@ -44,6 +45,9 @@ static GLOBAL_ROOT_CONFIG: Lazy = #[allow(dead_code)] #[derive(Debug, Serialize, Deserialize, Clone)] pub struct RootConfig { + #[serde(default)] + pub location: PathBuf, + #[serde(default)] pub protocols: ProtocolConfig, @@ -53,13 +57,18 @@ pub struct RootConfig { #[serde(default)] pub registries: HashMap, - pub consumers: HashMap, + #[serde(default)] + pub consumer: ConsumerConfig, + + #[serde(default)] + pub services: HashMap, } impl Default for RootConfig { fn default() -> RootConfig { let conf: HashMap = yaml_file_parser(get_config_location()).unwrap(); - let root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); + let mut root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); + root_config.location = get_config_location(); root_config } } diff --git a/config/src/location.rs b/config/src/location.rs index cffbaeed..b4384ec5 100644 --- a/config/src/location.rs +++ b/config/src/location.rs @@ -37,3 +37,7 @@ pub fn get_config_location() -> PathBuf { } path_buf } + +pub fn set_config_file_path(path: String) { + std::env::set_var(ENV_DUBBO_CONFIG_PATH, path); +} diff --git a/config/src/types/consumer.rs b/config/src/types/consumer.rs index 411add07..19a5e7cc 100644 --- a/config/src/types/consumer.rs +++ b/config/src/types/consumer.rs @@ -21,13 +21,16 @@ use serde::Deserialize; use serde::Serialize; use base::types::alias::{ - ClusterStrategy, GroupId, InterfaceName, ParamKey, ProtocolKey, RegistryId, ServiceName, + ClusterStrategy, FilterKey, GroupId, InterfaceName, ParamKey, ProtocolKey, RegistryId, + ServiceName, }; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct ConsumerConfig { #[serde(default)] - pub registry_ids: Vec, + pub registry_ids: Vec, + #[serde(default)] + pub filter: FilterKey, #[serde(default)] pub protocol_ids: Vec, #[serde(default)] diff --git a/config/src/types/provider.rs b/config/src/types/provider.rs index d21b1531..a45deb89 100644 --- a/config/src/types/provider.rs +++ b/config/src/types/provider.rs @@ -34,11 +34,7 @@ pub struct ProviderConfig { impl ProviderConfig { pub fn new() -> Self { - ProviderConfig { - registry_ids: vec![], - protocol_ids: vec![], - services: HashMap::new(), - } + ProviderConfig::default() } pub fn with_registry_ids(mut self, registry_ids: Vec) -> Self { diff --git a/config/src/types/service.rs b/config/src/types/service.rs index 76e59cea..b1ada5af 100644 --- a/config/src/types/service.rs +++ b/config/src/types/service.rs @@ -15,43 +15,17 @@ * limitations under the License. */ -use base::types::alias::ProtocolKey; +use base::types::alias::{GroupId, InterfaceName, ProtocolKey, Version}; use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct ServiceConfig { - pub version: String, - pub group: String, + #[serde(default)] + pub version: Version, + #[serde(default)] + pub group: GroupId, + #[serde(default)] pub protocol: ProtocolKey, - pub interface: String, -} - -impl ServiceConfig { - pub fn interface(self, interface: String) -> Self { - Self { interface, ..self } - } - - pub fn version(self, version: String) -> Self { - Self { version, ..self } - } - - pub fn group(self, group: String) -> Self { - Self { group, ..self } - } - - pub fn protocol(self, protocol: ProtocolKey) -> Self { - Self { protocol, ..self } - } - - // pub fn get_url(&self) -> Vec { - // let mut urls = Vec::new(); - // for (_, conf) in self.protocol_configs.iter() { - // urls.push(Url { - // url: conf.to_owned().to_url(), - // service_key: "".to_string(), - // }); - // } - - // urls - // } + #[serde(default)] + pub interface: InterfaceName, } diff --git a/config/src/util.rs b/config/src/util.rs index dcc5bacc..38ce8226 100644 --- a/config/src/util.rs +++ b/config/src/util.rs @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use std::any::{Any, TypeId}; use std::{collections::HashMap, fs, path::PathBuf, sync::Mutex}; use anyhow::Error; @@ -61,12 +62,23 @@ pub fn yaml_key_reader(path: PathBuf, key: &str) -> Result, Error Ok(Some(value.as_str().unwrap().to_string())) } +pub fn is_empty_value(value: T) -> bool { + if TypeId::of::() == TypeId::of::() { + return value.to_string().is_empty(); + } else if TypeId::of::() == TypeId::of::() { + return value.to_string() == "0"; + } else if TypeId::of::() == TypeId::of::() { + return value.to_string() == "0"; + } + false +} + #[cfg(test)] mod tests { use std::collections::HashMap; use utils::path_util::app_root_dir; - use crate::util::{yaml_file_parser, yaml_key_reader}; + use crate::util::{is_empty_value, yaml_file_parser, yaml_key_reader}; #[test] fn test_yaml_file_parser() { @@ -91,4 +103,12 @@ mod tests { let config = yaml_key_reader(path, "logging.file.path").unwrap(); println!("{:?}", config); } + + #[test] + fn test_is_empty_value() { + assert!(is_empty_value(0)); + assert!(is_empty_value(0.0)); + assert!(is_empty_value("".to_string())); + println!("&str is not empty{}", is_empty_value(0.0)); + } } diff --git a/config/tests/dubbo.yaml b/config/tests/dubbo.yaml index a28e1d9b..7ad54f4a 100644 --- a/config/tests/dubbo.yaml +++ b/config/tests/dubbo.yaml @@ -22,7 +22,7 @@ dubbo: serialization: hessian2 interface: org.apache.dubbo.samples.UserProviderTriple consumer: - filter: tracing + filter: "tracing" registry-ids: - demoZK references: diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 61cb9e10..b5ab8ab5 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -17,11 +17,34 @@ #[cfg(test)] mod tests_api { + use std::env; + use std::sync::Once; + + use ctor::ctor; + use config::get_root_config; + use config::location::set_config_file_path; + + static INIT: Once = Once::new(); + + #[ctor] + fn setup() { + INIT.call_once(|| { + set_config_file_path(format!( + "{}/{}", + env::current_dir() + .unwrap() + .into_os_string() + .to_str() + .unwrap(), + "tests" + )); + }); + } #[test] fn test_api_overwrite_yaml() { let root_config = get_root_config(); - println!("{:?}", root_config); + println!("{:#?}", root_config); } } From 72926e7e35c1ac7927459b6d5b34ee9657868e91 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 20:38:47 +0800 Subject: [PATCH 24/52] Ftr: config api --- common/base/src/types/alias.rs | 3 ++ config/Cargo.toml | 3 +- config/src/lib.rs | 13 +++++--- config/src/types/protocol.rs | 56 ++-------------------------------- config/src/types/provider.rs | 26 +--------------- config/src/types/registry.rs | 4 ++- config/src/types/service.rs | 11 +++++-- config/tests/dubbo.yaml | 4 +++ config/tests/test_api.rs | 17 +++++++++++ 9 files changed, 50 insertions(+), 87 deletions(-) diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs index c49ede63..69262935 100644 --- a/common/base/src/types/alias.rs +++ b/common/base/src/types/alias.rs @@ -22,6 +22,7 @@ pub type RegistryType = String; // protocolKey defined in protocol layer, mean specified protocol pub type ServiceName = String; pub type ServiceKey = String; +pub type SerializationKey = String; // pub type ProtocolKey = String; pub type GroupId = String; @@ -32,3 +33,5 @@ pub type InterfaceName = String; pub type ClusterStrategy = String; pub type FilterKey = String; pub type ParamKey = String; + +pub type Port = u32; diff --git a/config/Cargo.toml b/config/Cargo.toml index 3495cb77..36710540 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -19,5 +19,6 @@ anyhow.workspace = true base.workspace = true tracing.workspace = true tokio.workspace = true +getset.workspace = true [dev-dependencies] -ctor.workspace = true \ No newline at end of file +ctor.workspace = true diff --git a/config/src/lib.rs b/config/src/lib.rs index ab89dc34..7c41f823 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -16,7 +16,6 @@ */ use base::constants::DUBBO_KEY; -use base::types::alias::{RegistryId, ServiceName}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -33,6 +32,7 @@ use crate::types::provider::ProviderConfig; use crate::types::registry::RegistryConfig; use crate::types::service::ServiceConfig; use crate::util::yaml_file_parser; +use getset::{CopyGetters, Getters, MutGetters, Setters}; pub use location::get_config_location; pub type ConfigWrapper = Arc>; @@ -43,25 +43,30 @@ static GLOBAL_ROOT_CONFIG: Lazy = /// used to storage all structed config, from some source: cmd, file..; /// Impl Config trait, business init by read Config trait #[allow(dead_code)] -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, Getters, Setters, MutGetters, CopyGetters)] pub struct RootConfig { #[serde(default)] pub location: PathBuf, #[serde(default)] + #[getset(get, set, get_mut)] pub protocols: ProtocolConfig, #[serde(default)] + #[getset(get, set, get_mut)] pub provider: ProviderConfig, #[serde(default)] - pub registries: HashMap, + #[getset(get, set, get_mut)] + pub registries: RegistryConfig, #[serde(default)] + #[getset(get, set, get_mut)] pub consumer: ConsumerConfig, #[serde(default)] - pub services: HashMap, + #[getset(get, set, get_mut)] + pub services: ServiceConfig, } impl Default for RootConfig { diff --git a/config/src/types/protocol.rs b/config/src/types/protocol.rs index 54f893c1..176acfa6 100644 --- a/config/src/types/protocol.rs +++ b/config/src/types/protocol.rs @@ -17,13 +17,13 @@ use std::collections::HashMap; -use base::types::alias::{ParamKey, ProtocolKey}; +use base::types::alias::{ParamKey, Port, ProtocolKey}; use serde::{Deserialize, Serialize}; #[derive(Default, Debug, Clone, Serialize, Deserialize)] pub struct Protocol { pub ip: String, - pub port: String, + pub port: Port, pub name: ProtocolKey, #[serde(skip_serializing, skip_deserializing)] @@ -31,55 +31,3 @@ pub struct Protocol { } pub type ProtocolConfig = HashMap; - -pub trait ProtocolRetrieve { - fn get_protocol(&self, protocol_key: &str) -> Option; - fn get_protocol_or_default(&self, protocol_key: &str) -> Protocol; -} - -impl Protocol { - pub fn name(self, name: String) -> Self { - Self { name, ..self } - } - - pub fn ip(self, ip: String) -> Self { - Self { ip, ..self } - } - - pub fn port(self, port: String) -> Self { - Self { port, ..self } - } - - pub fn params(self, params: HashMap) -> Self { - Self { params, ..self } - } - - pub fn to_url(self) -> String { - format!("{}://{}:{}", self.name, self.ip, self.port) - } -} - -impl ProtocolRetrieve for ProtocolConfig { - fn get_protocol(&self, protocol_key: &str) -> Option { - let result = self.get(protocol_key); - if let Some(..) = result { - Some(result.unwrap().clone()) - } else { - None - } - } - - fn get_protocol_or_default(&self, protocol_key: &str) -> Protocol { - let result = self.get_protocol(protocol_key); - if let Some(..) = result { - result.unwrap() - } else { - let result = self.get_protocol(protocol_key); - if let Some(..) = result { - panic!("default triple base dose not defined.") - } else { - result.unwrap() - } - } - } -} diff --git a/config/src/types/provider.rs b/config/src/types/provider.rs index a45deb89..6875df81 100644 --- a/config/src/types/provider.rs +++ b/config/src/types/provider.rs @@ -15,9 +15,6 @@ * limitations under the License. */ -use std::collections::HashMap; - -use base::types::alias::ServiceName; use serde::{Deserialize, Serialize}; use super::service::ServiceConfig; @@ -29,26 +26,5 @@ pub struct ProviderConfig { #[serde(default)] pub protocol_ids: Vec, #[serde(default)] - pub services: HashMap, -} - -impl ProviderConfig { - pub fn new() -> Self { - ProviderConfig::default() - } - - pub fn with_registry_ids(mut self, registry_ids: Vec) -> Self { - self.registry_ids = registry_ids; - self - } - - pub fn with_protocol_ids(mut self, protocol_ids: Vec) -> Self { - self.protocol_ids = protocol_ids; - self - } - - pub fn with_services(mut self, services: HashMap) -> Self { - self.services = services; - self - } + pub services: ServiceConfig, } diff --git a/config/src/types/registry.rs b/config/src/types/registry.rs index 93a6f254..5499fadf 100644 --- a/config/src/types/registry.rs +++ b/config/src/types/registry.rs @@ -19,8 +19,10 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::time::Duration; +pub type RegistryConfig = HashMap; + #[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct RegistryConfig { +pub struct Registry { #[serde(default)] pub protocol: RegistryId, #[serde(default)] diff --git a/config/src/types/service.rs b/config/src/types/service.rs index b1ada5af..aef36727 100644 --- a/config/src/types/service.rs +++ b/config/src/types/service.rs @@ -15,11 +15,16 @@ * limitations under the License. */ -use base::types::alias::{GroupId, InterfaceName, ProtocolKey, Version}; +use base::types::alias::{ + GroupId, InterfaceName, ProtocolKey, SerializationKey, ServiceName, Version, +}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +pub type ServiceConfig = HashMap; #[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct ServiceConfig { +pub struct Service { #[serde(default)] pub version: Version, #[serde(default)] @@ -28,4 +33,6 @@ pub struct ServiceConfig { pub protocol: ProtocolKey, #[serde(default)] pub interface: InterfaceName, + #[serde(default)] + pub serialization: SerializationKey, } diff --git a/config/tests/dubbo.yaml b/config/tests/dubbo.yaml index 7ad54f4a..3da71a52 100644 --- a/config/tests/dubbo.yaml +++ b/config/tests/dubbo.yaml @@ -8,6 +8,10 @@ dubbo: ip: 0.0.0.0 port: 8888 name: tri + dubbo: + ip: 0.0.0.0 + port: 8888 + name: tri registries: demoZK: protocol: zookeeper diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index b5ab8ab5..2b3dbba4 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -46,5 +46,22 @@ mod tests_api { fn test_api_overwrite_yaml() { let root_config = get_root_config(); println!("{:#?}", root_config); + root_config + .lock() + .unwrap() + .protocols + .get_mut("dubbo") + .unwrap() + .port = 20987; + assert_eq!( + root_config + .lock() + .unwrap() + .protocols + .get("dubbo") + .unwrap() + .port, + 20987 + ); } } From de3746c4c760054e4ea909f249183249cc6811bf Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 21:29:38 +0800 Subject: [PATCH 25/52] Ftr: config api --- Cargo.toml | 1 + common/base/src/types/alias.rs | 2 +- config/Cargo.toml | 3 +- config/src/api.rs | 53 ++++++++++++++++++++++++++++++++++ config/src/error.rs | 25 ++++++++++++++++ config/src/lib.rs | 2 ++ config/src/types/consumer.rs | 7 +++-- config/src/types/protocol.rs | 3 ++ config/tests/test_api.rs | 16 ++++++++-- 9 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 config/src/api.rs create mode 100644 config/src/error.rs diff --git a/Cargo.toml b/Cargo.toml index 6f9f29ef..da36ce04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,5 +58,6 @@ once_cell = "1.16.0" itertools = "0.10.1" ctor = "0.1.23" getset = "0.1.2" +thiserror = "1.0.29" diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs index 69262935..50c30fa4 100644 --- a/common/base/src/types/alias.rs +++ b/common/base/src/types/alias.rs @@ -34,4 +34,4 @@ pub type ClusterStrategy = String; pub type FilterKey = String; pub type ParamKey = String; -pub type Port = u32; +pub type Port = String; diff --git a/config/Cargo.toml b/config/Cargo.toml index 36710540..06b89932 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -15,10 +15,11 @@ serde_yaml.workspace = true lazy_static.workspace = true once_cell.workspace = true utils.workspace = true -anyhow.workspace = true base.workspace = true tracing.workspace = true tokio.workspace = true getset.workspace = true +thiserror.workspace = true +anyhow.workspace = true [dev-dependencies] ctor.workspace = true diff --git a/config/src/api.rs b/config/src/api.rs new file mode 100644 index 00000000..78a1901d --- /dev/null +++ b/config/src/api.rs @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +use std::collections::HashMap; + +use crate::error::ConfigError; +use anyhow::{anyhow, Error, Result}; + +use crate::get_root_config; +use crate::types::protocol::Protocol; + +pub fn dubbo_set_protocol(protocol: &str, key: String, value: String) -> Result<(), Error> { + let root_config = get_root_config(); + let mut guard = root_config.lock().unwrap(); + if !guard.protocols().contains_key(protocol) { + guard + .protocols + .insert(protocol.to_string(), Protocol::default()); + } + let x = guard.protocols.get_mut(protocol).unwrap(); + match key.as_str() { + "ip" => x.ip = value, + "port" => x.port = value, + "name" => x.name = value, + _ => { + HashMap::insert(&mut x.params, key, value); + } + } + Ok(()) +} + +pub fn dubbo_get_protocol(protocol: &str) -> Result { + let root_config = get_root_config(); + let guard = root_config.lock().unwrap(); + if !guard.protocols.contains_key(protocol) { + return Err(anyhow!(ConfigError::ProtocolNotFound(protocol.to_string()))); + } + Ok(guard.protocols.get(protocol).unwrap().clone()) +} diff --git a/config/src/error.rs b/config/src/error.rs new file mode 100644 index 00000000..5c9b172c --- /dev/null +++ b/config/src/error.rs @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +use thiserror::Error; +#[derive(Error, Debug)] +pub enum ConfigError { + #[error("protocol {0} not found.")] + ProtocolNotFound(String), + #[error("Unknown error")] + Unknown, +} diff --git a/config/src/lib.rs b/config/src/lib.rs index 7c41f823..31c7a042 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -22,6 +22,8 @@ use std::collections::HashMap; use std::path::PathBuf; use std::sync::{Arc, Mutex}; +pub mod api; +pub mod error; pub mod location; pub mod types; pub mod util; diff --git a/config/src/types/consumer.rs b/config/src/types/consumer.rs index 19a5e7cc..4bc496b3 100644 --- a/config/src/types/consumer.rs +++ b/config/src/types/consumer.rs @@ -34,10 +34,13 @@ pub struct ConsumerConfig { #[serde(default)] pub protocol_ids: Vec, #[serde(default)] - pub references: HashMap, + pub references: ReferenceConfig, } + +pub type ReferenceConfig = HashMap; + #[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct ReferenceConfig { +pub struct Reference { #[serde(default)] pub url: String, #[serde(default)] diff --git a/config/src/types/protocol.rs b/config/src/types/protocol.rs index 176acfa6..caa9620a 100644 --- a/config/src/types/protocol.rs +++ b/config/src/types/protocol.rs @@ -22,8 +22,11 @@ use serde::{Deserialize, Serialize}; #[derive(Default, Debug, Clone, Serialize, Deserialize)] pub struct Protocol { + #[serde(default)] pub ip: String, + #[serde(default)] pub port: Port, + #[serde(default)] pub name: ProtocolKey, #[serde(skip_serializing, skip_deserializing)] diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 2b3dbba4..3c06696c 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -20,6 +20,7 @@ mod tests_api { use std::env; use std::sync::Once; + use config::api::{dubbo_get_protocol, dubbo_set_protocol}; use ctor::ctor; use config::get_root_config; @@ -52,7 +53,7 @@ mod tests_api { .protocols .get_mut("dubbo") .unwrap() - .port = 20987; + .port = "20987".to_string(); assert_eq!( root_config .lock() @@ -61,7 +62,18 @@ mod tests_api { .get("dubbo") .unwrap() .port, - 20987 + "20987".to_string() ); } + + #[test] + fn test_dubbo_set_protocol() { + dubbo_set_protocol("dubbo", "ip".to_string(), "122.22.22.22".to_string()).unwrap(); + dubbo_set_protocol("dubbo", "port".to_string(), "111".to_string()).unwrap(); + dubbo_set_protocol("dubbo", "name".to_string(), "dubbo".to_string()).unwrap(); + dubbo_set_protocol("dubbo", "nam1e".to_string(), "dubbo".to_string()).unwrap(); + let result = dubbo_get_protocol("dubbo").unwrap(); + assert_eq!(result.port, "111".to_string()); + assert_eq!(result.name, "dubbo".to_string()); + } } From 143920dbb20f11e6c7ba38720a0085f8c8f6689a Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 21:49:58 +0800 Subject: [PATCH 26/52] Ftr: config api --- config/src/api.rs | 53 +++++++++++++++++--------------- config/src/lib.rs | 61 ++++--------------------------------- config/src/types/mod.rs | 66 ++++++++++++++++++++++++++++++++++++++++ config/tests/test_api.rs | 26 ++-------------- 4 files changed, 103 insertions(+), 103 deletions(-) diff --git a/config/src/api.rs b/config/src/api.rs index 78a1901d..6e254e05 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -20,34 +20,39 @@ use std::collections::HashMap; use crate::error::ConfigError; use anyhow::{anyhow, Error, Result}; -use crate::get_root_config; use crate::types::protocol::Protocol; +use crate::ConfigWrapper; -pub fn dubbo_set_protocol(protocol: &str, key: String, value: String) -> Result<(), Error> { - let root_config = get_root_config(); - let mut guard = root_config.lock().unwrap(); - if !guard.protocols().contains_key(protocol) { - guard - .protocols - .insert(protocol.to_string(), Protocol::default()); - } - let x = guard.protocols.get_mut(protocol).unwrap(); - match key.as_str() { - "ip" => x.ip = value, - "port" => x.port = value, - "name" => x.name = value, - _ => { - HashMap::insert(&mut x.params, key, value); +pub trait ConfigApi { + fn dubbo_set_protocol(&self, protocol: &str, key: String, value: String) -> Result<(), Error>; + fn dubbo_get_protocol(&self, protocol: &str) -> Result; +} + +impl ConfigApi for ConfigWrapper { + fn dubbo_set_protocol(&self, protocol: &str, key: String, value: String) -> Result<(), Error> { + let mut guard = self.inner.lock().unwrap(); + if !guard.protocols.contains_key(protocol) { + guard + .protocols + .insert(protocol.to_string(), Protocol::default()); } + let x = guard.protocols.get_mut(protocol).unwrap(); + match key.as_str() { + "ip" => x.ip = value, + "port" => x.port = value, + "name" => x.name = value, + _ => { + HashMap::insert(&mut x.params, key, value); + } + } + Ok(()) } - Ok(()) -} -pub fn dubbo_get_protocol(protocol: &str) -> Result { - let root_config = get_root_config(); - let guard = root_config.lock().unwrap(); - if !guard.protocols.contains_key(protocol) { - return Err(anyhow!(ConfigError::ProtocolNotFound(protocol.to_string()))); + fn dubbo_get_protocol(&self, protocol: &str) -> Result { + let guard = self.inner.lock().unwrap(); + if !guard.protocols.contains_key(protocol) { + return Err(anyhow!(ConfigError::ProtocolNotFound(protocol.to_string()))); + } + Ok(guard.protocols.get(protocol).unwrap().clone()) } - Ok(guard.protocols.get(protocol).unwrap().clone()) } diff --git a/config/src/lib.rs b/config/src/lib.rs index 31c7a042..8f79c2ac 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -15,70 +15,21 @@ * limitations under the License. */ -use base::constants::DUBBO_KEY; use once_cell::sync::Lazy; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use std::path::PathBuf; use std::sync::{Arc, Mutex}; +pub use crate::types::ConfigWrapper; +pub use crate::types::RootConfig; +pub use location::get_config_location; + pub mod api; pub mod error; pub mod location; pub mod types; pub mod util; -use crate::types::consumer::ConsumerConfig; -use crate::types::protocol::ProtocolConfig; -use crate::types::provider::ProviderConfig; -use crate::types::registry::RegistryConfig; -use crate::types::service::ServiceConfig; -use crate::util::yaml_file_parser; -use getset::{CopyGetters, Getters, MutGetters, Setters}; -pub use location::get_config_location; - -pub type ConfigWrapper = Arc>; - -static GLOBAL_ROOT_CONFIG: Lazy = - Lazy::new(|| Arc::new(Mutex::new(RootConfig::default()))); - -/// used to storage all structed config, from some source: cmd, file..; -/// Impl Config trait, business init by read Config trait -#[allow(dead_code)] -#[derive(Debug, Serialize, Deserialize, Clone, Getters, Setters, MutGetters, CopyGetters)] -pub struct RootConfig { - #[serde(default)] - pub location: PathBuf, - - #[serde(default)] - #[getset(get, set, get_mut)] - pub protocols: ProtocolConfig, - - #[serde(default)] - #[getset(get, set, get_mut)] - pub provider: ProviderConfig, - - #[serde(default)] - #[getset(get, set, get_mut)] - pub registries: RegistryConfig, - - #[serde(default)] - #[getset(get, set, get_mut)] - pub consumer: ConsumerConfig, - - #[serde(default)] - #[getset(get, set, get_mut)] - pub services: ServiceConfig, -} - -impl Default for RootConfig { - fn default() -> RootConfig { - let conf: HashMap = yaml_file_parser(get_config_location()).unwrap(); - let mut root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); - root_config.location = get_config_location(); - root_config - } -} +pub(crate) static GLOBAL_ROOT_CONFIG: Lazy = + Lazy::new(|| ConfigWrapper::new(Arc::new(Mutex::new(RootConfig::default())))); pub fn get_root_config() -> ConfigWrapper { GLOBAL_ROOT_CONFIG.clone() diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index ab38fa9c..356e78ad 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -15,8 +15,74 @@ * limitations under the License. */ +use crate::error::ConfigError; +use crate::types::consumer::ConsumerConfig; +use crate::types::protocol::{Protocol, ProtocolConfig}; +use crate::types::provider::ProviderConfig; +use crate::types::registry::RegistryConfig; +use crate::types::service::ServiceConfig; +use crate::util::yaml_file_parser; +use crate::{get_config_location, get_root_config}; +use anyhow::{anyhow, Error}; +use base::constants::DUBBO_KEY; +use getset::{CopyGetters, Getters, MutGetters, Setters}; +use serde::Deserialize; +use serde::Serialize; +use std::collections::HashMap; +use std::path::PathBuf; +use std::sync::{Arc, Mutex}; + pub mod consumer; pub mod protocol; pub mod provider; pub mod registry; pub mod service; + +/// used to storage all structed config, from some source: cmd, file..; +/// Impl Config trait, business init by read Config trait +#[allow(dead_code)] +#[derive(Debug, Serialize, Deserialize, Clone, Getters, Setters, MutGetters, CopyGetters)] +pub struct RootConfig { + #[serde(default)] + pub location: PathBuf, + + #[serde(default)] + #[getset(get, set, get_mut)] + pub protocols: ProtocolConfig, + + #[serde(default)] + #[getset(get, set, get_mut)] + pub provider: ProviderConfig, + + #[serde(default)] + #[getset(get, set, get_mut)] + pub registries: RegistryConfig, + + #[serde(default)] + #[getset(get, set, get_mut)] + pub consumer: ConsumerConfig, + + #[serde(default)] + #[getset(get, set, get_mut)] + pub services: ServiceConfig, +} + +impl Default for RootConfig { + fn default() -> RootConfig { + let conf: HashMap = yaml_file_parser(get_config_location()).unwrap(); + let mut root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); + root_config.location = get_config_location(); + root_config + } +} + +#[derive(Clone)] +pub struct ConfigWrapper { + pub inner: Arc>, +} + +impl ConfigWrapper { + pub fn new(inner: Arc>) -> Self { + ConfigWrapper { inner } + } +} diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 3c06696c..adc6abf6 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -20,7 +20,6 @@ mod tests_api { use std::env; use std::sync::Once; - use config::api::{dubbo_get_protocol, dubbo_set_protocol}; use ctor::ctor; use config::get_root_config; @@ -43,31 +42,10 @@ mod tests_api { }); } - #[test] - fn test_api_overwrite_yaml() { - let root_config = get_root_config(); - println!("{:#?}", root_config); - root_config - .lock() - .unwrap() - .protocols - .get_mut("dubbo") - .unwrap() - .port = "20987".to_string(); - assert_eq!( - root_config - .lock() - .unwrap() - .protocols - .get("dubbo") - .unwrap() - .port, - "20987".to_string() - ); - } - #[test] fn test_dubbo_set_protocol() { + let config_wrapper = get_root_config(); + dubbo_set_protocol("dubbo", "ip".to_string(), "122.22.22.22".to_string()).unwrap(); dubbo_set_protocol("dubbo", "port".to_string(), "111".to_string()).unwrap(); dubbo_set_protocol("dubbo", "name".to_string(), "dubbo".to_string()).unwrap(); From 1c7c55d24c532f8b31b630d32731984ec1f94bb5 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 22:46:31 +0800 Subject: [PATCH 27/52] Ftr: config api --- config/src/api.rs | 2 ++ config/src/types/mod.rs | 6 ++---- config/tests/test_api.rs | 29 ++++++++++++++++++++--------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/config/src/api.rs b/config/src/api.rs index 6e254e05..45626070 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -23,6 +23,8 @@ use anyhow::{anyhow, Error, Result}; use crate::types::protocol::Protocol; use crate::ConfigWrapper; +// could be used for config_center + pub trait ConfigApi { fn dubbo_set_protocol(&self, protocol: &str, key: String, value: String) -> Result<(), Error>; fn dubbo_get_protocol(&self, protocol: &str) -> Result; diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index 356e78ad..2b1035c5 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -15,15 +15,13 @@ * limitations under the License. */ -use crate::error::ConfigError; +use crate::get_config_location; use crate::types::consumer::ConsumerConfig; -use crate::types::protocol::{Protocol, ProtocolConfig}; +use crate::types::protocol::ProtocolConfig; use crate::types::provider::ProviderConfig; use crate::types::registry::RegistryConfig; use crate::types::service::ServiceConfig; use crate::util::yaml_file_parser; -use crate::{get_config_location, get_root_config}; -use anyhow::{anyhow, Error}; use base::constants::DUBBO_KEY; use getset::{CopyGetters, Getters, MutGetters, Setters}; use serde::Deserialize; diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index adc6abf6..6de6e3f7 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -22,6 +22,7 @@ mod tests_api { use ctor::ctor; + use config::api::ConfigApi; use config::get_root_config; use config::location::set_config_file_path; @@ -30,6 +31,7 @@ mod tests_api { #[ctor] fn setup() { INIT.call_once(|| { + println!("load config file."); set_config_file_path(format!( "{}/{}", env::current_dir() @@ -43,15 +45,24 @@ mod tests_api { } #[test] - fn test_dubbo_set_protocol() { + fn test_dubbo_set_protocol_overwrite_yaml_by_api() { let config_wrapper = get_root_config(); - - dubbo_set_protocol("dubbo", "ip".to_string(), "122.22.22.22".to_string()).unwrap(); - dubbo_set_protocol("dubbo", "port".to_string(), "111".to_string()).unwrap(); - dubbo_set_protocol("dubbo", "name".to_string(), "dubbo".to_string()).unwrap(); - dubbo_set_protocol("dubbo", "nam1e".to_string(), "dubbo".to_string()).unwrap(); - let result = dubbo_get_protocol("dubbo").unwrap(); - assert_eq!(result.port, "111".to_string()); - assert_eq!(result.name, "dubbo".to_string()); + let old_config = config_wrapper.dubbo_get_protocol("dubbo").unwrap(); + assert_eq!(old_config.port, "8888".to_string()); + config_wrapper + .dubbo_set_protocol("dubbo", "ip".to_string(), "122.22.22.22".to_string()) + .unwrap(); + config_wrapper + .dubbo_set_protocol("dubbo", "port".to_string(), "111".to_string()) + .unwrap(); + config_wrapper + .dubbo_set_protocol("dubbo", "name".to_string(), "dubbo".to_string()) + .unwrap(); + config_wrapper + .dubbo_set_protocol("dubbo", "nam1e".to_string(), "dubbo".to_string()) + .unwrap(); + let new_config = config_wrapper.dubbo_get_protocol("dubbo").unwrap(); + assert_eq!(new_config.port, "111".to_string()); + assert_eq!(new_config.name, "dubbo".to_string()); } } From e2128d79abba3b76fdf0c76384ddf2a5cb90575f Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 23:15:05 +0800 Subject: [PATCH 28/52] Ftr: config api --- config/src/api.rs | 87 ++++++++++++++++++++ config/src/error.rs | 2 + config/src/types/mod.rs | 6 +- config/src/types/provider.rs | 2 +- config/src/types/registry.rs | 2 +- config/src/types/{service.rs => services.rs} | 2 +- 6 files changed, 95 insertions(+), 6 deletions(-) rename config/src/types/{service.rs => services.rs} (95%) diff --git a/config/src/api.rs b/config/src/api.rs index 45626070..0dbf7a1a 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -21,6 +21,8 @@ use crate::error::ConfigError; use anyhow::{anyhow, Error, Result}; use crate::types::protocol::Protocol; +use crate::types::registry::Registry; +use crate::types::services::Service; use crate::ConfigWrapper; // could be used for config_center @@ -28,6 +30,20 @@ use crate::ConfigWrapper; pub trait ConfigApi { fn dubbo_set_protocol(&self, protocol: &str, key: String, value: String) -> Result<(), Error>; fn dubbo_get_protocol(&self, protocol: &str) -> Result; + fn dubbo_get_registry(&self, registry_id: &str) -> Result; + fn dubbo_set_registry( + &self, + registry_id: &str, + key: String, + value: String, + ) -> Result<(), Error>; + fn dubbo_get_services(&self, service_name: &str) -> Result; + fn dubbo_set_services( + &self, + service_name: &str, + key: String, + value: String, + ) -> Result<(), Error>; } impl ConfigApi for ConfigWrapper { @@ -57,4 +73,75 @@ impl ConfigApi for ConfigWrapper { } Ok(guard.protocols.get(protocol).unwrap().clone()) } + + fn dubbo_get_registry(&self, registry_id: &str) -> Result { + let guard = self.inner.lock().unwrap(); + if !guard.registries.contains_key(registry_id) { + return Err(anyhow!(ConfigError::RegistryNotFound( + registry_id.to_string() + ))); + } + Ok(guard.registries.get(registry_id).unwrap().clone()) + } + + fn dubbo_set_registry( + &self, + registry_id: &str, + key: String, + value: String, + ) -> Result<(), Error> { + let mut guard = self.inner.lock().unwrap(); + if !guard.registries.contains_key(registry_id) { + guard + .registries + .insert(registry_id.to_string(), Registry::default()); + } + let x = guard.registries.get_mut(registry_id).unwrap(); + match key.as_str() { + "protocol" => x.protocol = value, + "registry_type" => x.registry_type = value, + "address" => x.address = value, + "password" => x.password = value, + "username" => x.username = value, + "timeout" => x.timeout = value, + _ => { + HashMap::insert(&mut x.params, key, value); + } + } + Ok(()) + } + + fn dubbo_get_services(&self, service_name: &str) -> Result { + let guard = self.inner.lock().unwrap(); + if !guard.services.contains_key(service_name) { + return Err(anyhow!(ConfigError::RegistryNotFound( + service_name.to_string() + ))); + } + Ok(guard.services.get(service_name).unwrap().clone()) + } + + fn dubbo_set_services( + &self, + service_name: &str, + key: String, + value: String, + ) -> Result<(), Error> { + let mut guard = self.inner.lock().unwrap(); + if !guard.services.contains_key(service_name) { + guard + .services + .insert(service_name.to_string(), Service::default()); + } + let x = guard.services.get_mut(service_name).unwrap(); + match key.as_str() { + "protocol" => x.protocol = value, + "interface" => x.interface = value, + "group" => x.group = value, + "version" => x.version = value, + "serialization" => x.serialization = value, + _ => {} + } + Ok(()) + } } diff --git a/config/src/error.rs b/config/src/error.rs index 5c9b172c..564362b5 100644 --- a/config/src/error.rs +++ b/config/src/error.rs @@ -20,6 +20,8 @@ use thiserror::Error; pub enum ConfigError { #[error("protocol {0} not found.")] ProtocolNotFound(String), + #[error("registry {0} not found.")] + RegistryNotFound(String), #[error("Unknown error")] Unknown, } diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index 2b1035c5..5eb1ba43 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -20,7 +20,7 @@ use crate::types::consumer::ConsumerConfig; use crate::types::protocol::ProtocolConfig; use crate::types::provider::ProviderConfig; use crate::types::registry::RegistryConfig; -use crate::types::service::ServiceConfig; +use crate::types::services::ServicesConfig; use crate::util::yaml_file_parser; use base::constants::DUBBO_KEY; use getset::{CopyGetters, Getters, MutGetters, Setters}; @@ -34,7 +34,7 @@ pub mod consumer; pub mod protocol; pub mod provider; pub mod registry; -pub mod service; +pub mod services; /// used to storage all structed config, from some source: cmd, file..; /// Impl Config trait, business init by read Config trait @@ -62,7 +62,7 @@ pub struct RootConfig { #[serde(default)] #[getset(get, set, get_mut)] - pub services: ServiceConfig, + pub services: ServicesConfig, } impl Default for RootConfig { diff --git a/config/src/types/provider.rs b/config/src/types/provider.rs index 6875df81..0955a457 100644 --- a/config/src/types/provider.rs +++ b/config/src/types/provider.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; -use super::service::ServiceConfig; +use super::services::ServiceConfig; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct ProviderConfig { diff --git a/config/src/types/registry.rs b/config/src/types/registry.rs index 5499fadf..1cbed518 100644 --- a/config/src/types/registry.rs +++ b/config/src/types/registry.rs @@ -26,7 +26,7 @@ pub struct Registry { #[serde(default)] pub protocol: RegistryId, #[serde(default)] - pub timeout: Duration, + pub timeout: String, #[serde(default)] pub address: String, #[serde(default)] diff --git a/config/src/types/service.rs b/config/src/types/services.rs similarity index 95% rename from config/src/types/service.rs rename to config/src/types/services.rs index aef36727..50084373 100644 --- a/config/src/types/service.rs +++ b/config/src/types/services.rs @@ -21,7 +21,7 @@ use base::types::alias::{ use serde::{Deserialize, Serialize}; use std::collections::HashMap; -pub type ServiceConfig = HashMap; +pub type ServicesConfig = HashMap; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct Service { From a3844ddea05dfd5f22626b775ebe76b003bf96b4 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 23:29:05 +0800 Subject: [PATCH 29/52] Ftr: config api --- config/src/api.rs | 96 +++++++++++++++++++++++++++++++++++- config/src/error.rs | 6 ++- config/src/types/consumer.rs | 4 +- config/src/types/provider.rs | 5 +- config/src/types/registry.rs | 7 +-- 5 files changed, 107 insertions(+), 11 deletions(-) diff --git a/config/src/api.rs b/config/src/api.rs index 0dbf7a1a..7641eab9 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -20,6 +20,7 @@ use std::collections::HashMap; use crate::error::ConfigError; use anyhow::{anyhow, Error, Result}; +use crate::types::consumer::Reference; use crate::types::protocol::Protocol; use crate::types::registry::Registry; use crate::types::services::Service; @@ -44,6 +45,21 @@ pub trait ConfigApi { key: String, value: String, ) -> Result<(), Error>; + fn dubbo_provider_get_services(&self, service_name: &str) -> Result; + fn dubbo_provider_set_services( + &self, + service_name: &str, + key: String, + value: String, + ) -> Result<(), Error>; + + fn dubbo_consumer_get_references(&self, service_name: &str) -> Result; + fn dubbo_consumer_set_references( + &self, + service_name: &str, + key: String, + value: String, + ) -> Result<(), Error>; } impl ConfigApi for ConfigWrapper { @@ -114,7 +130,7 @@ impl ConfigApi for ConfigWrapper { fn dubbo_get_services(&self, service_name: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.services.contains_key(service_name) { - return Err(anyhow!(ConfigError::RegistryNotFound( + return Err(anyhow!(ConfigError::ServiceNotFound( service_name.to_string() ))); } @@ -140,7 +156,83 @@ impl ConfigApi for ConfigWrapper { "group" => x.group = value, "version" => x.version = value, "serialization" => x.serialization = value, - _ => {} + _ => { + return Err(anyhow!(ConfigError::UnsupportedKey(key))); + } + } + Ok(()) + } + + fn dubbo_provider_get_services(&self, service_name: &str) -> Result { + let guard = self.inner.lock().unwrap(); + if !guard.services.contains_key(service_name) { + return Err(anyhow!(ConfigError::ServiceNotFound( + service_name.to_string() + ))); + } + Ok(guard.services.get(service_name).unwrap().clone()) + } + + fn dubbo_provider_set_services( + &self, + service_name: &str, + key: String, + value: String, + ) -> Result<(), Error> { + let mut guard = self.inner.lock().unwrap(); + if !guard.provider.services.contains_key(service_name) { + guard + .services + .insert(service_name.to_string(), Service::default()); + } + let x = guard.provider.services.get_mut(service_name).unwrap(); + match key.as_str() { + "protocol" => x.protocol = value, + "interface" => x.interface = value, + "group" => x.group = value, + "version" => x.version = value, + "serialization" => x.serialization = value, + _ => { + return Err(anyhow!(ConfigError::UnsupportedKey(key))); + } + } + Ok(()) + } + + fn dubbo_consumer_get_references(&self, service_name: &str) -> Result { + let guard = self.inner.lock().unwrap(); + if !guard.consumer.references.contains_key(service_name) { + return Err(anyhow!(ConfigError::ServiceNotFound( + service_name.to_string() + ))); + } + Ok(guard.consumer.references.get(service_name).unwrap().clone()) + } + + fn dubbo_consumer_set_references( + &self, + service_name: &str, + key: String, + value: String, + ) -> Result<(), Error> { + let mut guard = self.inner.lock().unwrap(); + if !guard.consumer.references.contains_key(service_name) { + guard + .services + .insert(service_name.to_string(), Service::default()); + } + let x = guard.consumer.references.get_mut(service_name).unwrap(); + match key.as_str() { + "protocol" => x.protocol = value, + "interface" => x.interface = value, + "group" => x.group = value, + "cluster" => x.cluster = value, + "retries" => x.retries = value, + "url" => x.url = value, + "registry_ids" => x.registry_ids = value.split(',').map(|x| x.to_string()).collect(), + _ => { + return Err(anyhow!(ConfigError::UnsupportedKey(key))); + } } Ok(()) } diff --git a/config/src/error.rs b/config/src/error.rs index 564362b5..79d05879 100644 --- a/config/src/error.rs +++ b/config/src/error.rs @@ -22,6 +22,10 @@ pub enum ConfigError { ProtocolNotFound(String), #[error("registry {0} not found.")] RegistryNotFound(String), - #[error("Unknown error")] + #[error("service {0} not found.")] + ServiceNotFound(String), + #[error("unsupported key {0}.")] + UnsupportedKey(String), + #[error("Service error")] Unknown, } diff --git a/config/src/types/consumer.rs b/config/src/types/consumer.rs index 4bc496b3..3f8e8c80 100644 --- a/config/src/types/consumer.rs +++ b/config/src/types/consumer.rs @@ -48,7 +48,7 @@ pub struct Reference { #[serde(default)] pub group: GroupId, #[serde(default)] - pub interface_name: InterfaceName, + pub interface: InterfaceName, #[serde(default)] pub registry_ids: Vec, #[serde(default)] @@ -56,5 +56,5 @@ pub struct Reference { #[serde(default)] pub params: HashMap, #[serde(default)] - pub retries: u8, + pub retries: String, } diff --git a/config/src/types/provider.rs b/config/src/types/provider.rs index 0955a457..35946717 100644 --- a/config/src/types/provider.rs +++ b/config/src/types/provider.rs @@ -15,10 +15,9 @@ * limitations under the License. */ +use crate::types::services::ServicesConfig; use serde::{Deserialize, Serialize}; -use super::services::ServiceConfig; - #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct ProviderConfig { #[serde(default)] @@ -26,5 +25,5 @@ pub struct ProviderConfig { #[serde(default)] pub protocol_ids: Vec, #[serde(default)] - pub services: ServiceConfig, + pub services: ServicesConfig, } diff --git a/config/src/types/registry.rs b/config/src/types/registry.rs index 1cbed518..cf9e17c0 100644 --- a/config/src/types/registry.rs +++ b/config/src/types/registry.rs @@ -14,10 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use base::types::alias::{ParamKey, RegistryId, RegistryType}; -use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use std::time::Duration; + +use serde::{Deserialize, Serialize}; + +use base::types::alias::{ParamKey, RegistryId, RegistryType}; pub type RegistryConfig = HashMap; From 4d36be1de2727b925ede0eff8d48f7c60fbd769f Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 23:36:07 +0800 Subject: [PATCH 30/52] Ftr: config api --- config/src/api.rs | 15 ++++++++++++--- config/src/error.rs | 4 ++-- config/src/util.rs | 13 +++++-------- config/tests/test_config.rs | 16 ---------------- 4 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 config/tests/test_config.rs diff --git a/config/src/api.rs b/config/src/api.rs index 7641eab9..4ae2b9c9 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -157,7 +157,10 @@ impl ConfigApi for ConfigWrapper { "version" => x.version = value, "serialization" => x.serialization = value, _ => { - return Err(anyhow!(ConfigError::UnsupportedKey(key))); + return Err(anyhow!(ConfigError::UnsupportedKey( + "services".to_string(), + key + ))); } } Ok(()) @@ -193,7 +196,10 @@ impl ConfigApi for ConfigWrapper { "version" => x.version = value, "serialization" => x.serialization = value, _ => { - return Err(anyhow!(ConfigError::UnsupportedKey(key))); + return Err(anyhow!(ConfigError::UnsupportedKey( + "provider.services".to_string(), + key + ))); } } Ok(()) @@ -231,7 +237,10 @@ impl ConfigApi for ConfigWrapper { "url" => x.url = value, "registry_ids" => x.registry_ids = value.split(',').map(|x| x.to_string()).collect(), _ => { - return Err(anyhow!(ConfigError::UnsupportedKey(key))); + return Err(anyhow!(ConfigError::UnsupportedKey( + "consumer.references".to_string(), + key + ))); } } Ok(()) diff --git a/config/src/error.rs b/config/src/error.rs index 79d05879..af019435 100644 --- a/config/src/error.rs +++ b/config/src/error.rs @@ -24,8 +24,8 @@ pub enum ConfigError { RegistryNotFound(String), #[error("service {0} not found.")] ServiceNotFound(String), - #[error("unsupported key {0}.")] - UnsupportedKey(String), + #[error("unsupported key {1} for {0}.")] + UnsupportedKey(String, String), #[error("Service error")] Unknown, } diff --git a/config/src/util.rs b/config/src/util.rs index 38ce8226..11744761 100644 --- a/config/src/util.rs +++ b/config/src/util.rs @@ -64,13 +64,11 @@ pub fn yaml_key_reader(path: PathBuf, key: &str) -> Result, Error pub fn is_empty_value(value: T) -> bool { if TypeId::of::() == TypeId::of::() { - return value.to_string().is_empty(); - } else if TypeId::of::() == TypeId::of::() { - return value.to_string() == "0"; - } else if TypeId::of::() == TypeId::of::() { - return value.to_string() == "0"; + let value_str = value.to_string(); + value_str.is_empty() || value_str.to_string() == "null" || value_str.to_string() == "0" + } else { + false } - false } #[cfg(test)] @@ -106,8 +104,7 @@ mod tests { #[test] fn test_is_empty_value() { - assert!(is_empty_value(0)); - assert!(is_empty_value(0.0)); + assert!(is_empty_value("0".to_string())); assert!(is_empty_value("".to_string())); println!("&str is not empty{}", is_empty_value(0.0)); } diff --git a/config/tests/test_config.rs b/config/tests/test_config.rs deleted file mode 100644 index 2944f981..00000000 --- a/config/tests/test_config.rs +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ From cec0ce7ef4d9468793dc36b0aaf9e77e07813121 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Mon, 6 Mar 2023 23:44:07 +0800 Subject: [PATCH 31/52] Ftr: config api --- config/src/api.rs | 40 ++++++++++++++++++++-------------------- config/tests/dubbo.yaml | 6 +++--- config/tests/test_api.rs | 14 +++++++------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/config/src/api.rs b/config/src/api.rs index 4ae2b9c9..ef563546 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -29,32 +29,32 @@ use crate::ConfigWrapper; // could be used for config_center pub trait ConfigApi { - fn dubbo_set_protocol(&self, protocol: &str, key: String, value: String) -> Result<(), Error>; - fn dubbo_get_protocol(&self, protocol: &str) -> Result; - fn dubbo_get_registry(&self, registry_id: &str) -> Result; - fn dubbo_set_registry( + fn dubbo_protocol_set(&self, protocol: &str, key: String, value: String) -> Result<(), Error>; + fn dubbo_protocol_get(&self, protocol: &str) -> Result; + fn dubbo_registry_get(&self, registry_id: &str) -> Result; + fn dubbo_registry_set( &self, registry_id: &str, key: String, value: String, ) -> Result<(), Error>; - fn dubbo_get_services(&self, service_name: &str) -> Result; - fn dubbo_set_services( + fn dubbo_services_get(&self, service_name: &str) -> Result; + fn dubbo_services_set( &self, service_name: &str, key: String, value: String, ) -> Result<(), Error>; - fn dubbo_provider_get_services(&self, service_name: &str) -> Result; - fn dubbo_provider_set_services( + fn dubbo_provider_services_get(&self, service_name: &str) -> Result; + fn dubbo_provider_services_set( &self, service_name: &str, key: String, value: String, ) -> Result<(), Error>; - fn dubbo_consumer_get_references(&self, service_name: &str) -> Result; - fn dubbo_consumer_set_references( + fn dubbo_consumer_references_get(&self, service_name: &str) -> Result; + fn dubbo_consumer_references_set( &self, service_name: &str, key: String, @@ -63,7 +63,7 @@ pub trait ConfigApi { } impl ConfigApi for ConfigWrapper { - fn dubbo_set_protocol(&self, protocol: &str, key: String, value: String) -> Result<(), Error> { + fn dubbo_protocol_set(&self, protocol: &str, key: String, value: String) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.protocols.contains_key(protocol) { guard @@ -82,7 +82,7 @@ impl ConfigApi for ConfigWrapper { Ok(()) } - fn dubbo_get_protocol(&self, protocol: &str) -> Result { + fn dubbo_protocol_get(&self, protocol: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.protocols.contains_key(protocol) { return Err(anyhow!(ConfigError::ProtocolNotFound(protocol.to_string()))); @@ -90,7 +90,7 @@ impl ConfigApi for ConfigWrapper { Ok(guard.protocols.get(protocol).unwrap().clone()) } - fn dubbo_get_registry(&self, registry_id: &str) -> Result { + fn dubbo_registry_get(&self, registry_id: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.registries.contains_key(registry_id) { return Err(anyhow!(ConfigError::RegistryNotFound( @@ -100,7 +100,7 @@ impl ConfigApi for ConfigWrapper { Ok(guard.registries.get(registry_id).unwrap().clone()) } - fn dubbo_set_registry( + fn dubbo_registry_set( &self, registry_id: &str, key: String, @@ -127,7 +127,7 @@ impl ConfigApi for ConfigWrapper { Ok(()) } - fn dubbo_get_services(&self, service_name: &str) -> Result { + fn dubbo_services_get(&self, service_name: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.services.contains_key(service_name) { return Err(anyhow!(ConfigError::ServiceNotFound( @@ -137,7 +137,7 @@ impl ConfigApi for ConfigWrapper { Ok(guard.services.get(service_name).unwrap().clone()) } - fn dubbo_set_services( + fn dubbo_services_set( &self, service_name: &str, key: String, @@ -166,7 +166,7 @@ impl ConfigApi for ConfigWrapper { Ok(()) } - fn dubbo_provider_get_services(&self, service_name: &str) -> Result { + fn dubbo_provider_services_get(&self, service_name: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.services.contains_key(service_name) { return Err(anyhow!(ConfigError::ServiceNotFound( @@ -176,7 +176,7 @@ impl ConfigApi for ConfigWrapper { Ok(guard.services.get(service_name).unwrap().clone()) } - fn dubbo_provider_set_services( + fn dubbo_provider_services_set( &self, service_name: &str, key: String, @@ -205,7 +205,7 @@ impl ConfigApi for ConfigWrapper { Ok(()) } - fn dubbo_consumer_get_references(&self, service_name: &str) -> Result { + fn dubbo_consumer_references_get(&self, service_name: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.consumer.references.contains_key(service_name) { return Err(anyhow!(ConfigError::ServiceNotFound( @@ -215,7 +215,7 @@ impl ConfigApi for ConfigWrapper { Ok(guard.consumer.references.get(service_name).unwrap().clone()) } - fn dubbo_consumer_set_references( + fn dubbo_consumer_references_set( &self, service_name: &str, key: String, diff --git a/config/tests/dubbo.yaml b/config/tests/dubbo.yaml index 3da71a52..ec3897e2 100644 --- a/config/tests/dubbo.yaml +++ b/config/tests/dubbo.yaml @@ -17,7 +17,7 @@ dubbo: protocol: zookeeper address: 0.0.0.0:2181 provider: - registry-ids: zk + registry_ids: zk services: UserProvider: serialization: hessian2 @@ -27,7 +27,7 @@ dubbo: interface: org.apache.dubbo.samples.UserProviderTriple consumer: filter: "tracing" - registry-ids: + registry_ids: - demoZK references: GreeterClientImpl: @@ -36,7 +36,7 @@ dubbo: retries: 5 services: "UserProvider": - registry-ids: "demoZk" + registry_ids: "demoZk" protocol: "dubbo" interface: "org.apache.dubbo.UserProvider" loadbalance: "random" diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 6de6e3f7..7aa2a9f5 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -45,23 +45,23 @@ mod tests_api { } #[test] - fn test_dubbo_set_protocol_overwrite_yaml_by_api() { + fn test_dubbo_protocol_set_overwrite_yaml_by_api() { let config_wrapper = get_root_config(); - let old_config = config_wrapper.dubbo_get_protocol("dubbo").unwrap(); + let old_config = config_wrapper.dubbo_protocol_get("dubbo").unwrap(); assert_eq!(old_config.port, "8888".to_string()); config_wrapper - .dubbo_set_protocol("dubbo", "ip".to_string(), "122.22.22.22".to_string()) + .dubbo_protocol_set("dubbo", "ip".to_string(), "122.22.22.22".to_string()) .unwrap(); config_wrapper - .dubbo_set_protocol("dubbo", "port".to_string(), "111".to_string()) + .dubbo_protocol_set("dubbo", "port".to_string(), "111".to_string()) .unwrap(); config_wrapper - .dubbo_set_protocol("dubbo", "name".to_string(), "dubbo".to_string()) + .dubbo_protocol_set("dubbo", "name".to_string(), "dubbo".to_string()) .unwrap(); config_wrapper - .dubbo_set_protocol("dubbo", "nam1e".to_string(), "dubbo".to_string()) + .dubbo_protocol_set("dubbo", "nam1e".to_string(), "dubbo".to_string()) .unwrap(); - let new_config = config_wrapper.dubbo_get_protocol("dubbo").unwrap(); + let new_config = config_wrapper.dubbo_protocol_get("dubbo").unwrap(); assert_eq!(new_config.port, "111".to_string()); assert_eq!(new_config.name, "dubbo".to_string()); } From 03f8ab908c007cd7e4b45af1b959effbdf87949c Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 08:58:22 +0800 Subject: [PATCH 32/52] Ftr: config api --- Cargo.toml | 64 ++++++++++++++++++------------------ common/base/src/constants.rs | 3 +- config/src/types/consumer.rs | 10 +++++- config/src/types/mod.rs | 5 +++ config/src/types/protocol.rs | 12 ++++++- config/src/types/registry.rs | 9 ++++- config/src/types/services.rs | 8 +++++ config/tests/dubbo.yaml | 7 ++-- config/tests/test_api.rs | 7 ++++ 9 files changed, 87 insertions(+), 38 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index da36ce04..1c4d05ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,26 +1,26 @@ [workspace] members = [ - "common/logger", - "common/utils", - "common/extention", - "common/base", - "registry/zookeeper", - "registry/nacos", - "metadata", - "config", - "dubbo", - "examples/echo", - "examples/greeter", - "dubbo-build", - "remoting/net", - "remoting/http", - "remoting/h2", - "remoting/zookeeper", - "remoting/exchange", - "remoting/xds", - "protocol/dubbo2", - "protocol/base", - "protocol/triple" + "common/logger", + "common/utils", + "common/extention", + "common/base", + "registry/zookeeper", + "registry/nacos", + "metadata", + "config", + "dubbo", + "examples/echo", + "examples/greeter", + "dubbo-build", + "remoting/net", + "remoting/http", + "remoting/h2", + "remoting/zookeeper", + "remoting/exchange", + "remoting/xds", + "protocol/dubbo2", + "protocol/base", + "protocol/triple" ] @@ -40,16 +40,16 @@ serde_json = "1" urlencoding = "2.1.2" tracing = "0.1" tracing-subscriber = "0.3" -logger = {path="./common/logger"} -utils = {path="./common/utils"} -base = {path="./common/base"} -config = {path="./config"} -remoting-net = {path="./remoting/net"} -protocol = {path= "protocol/base" } -protocol-dubbo2 = {path="./protocol/dubbo2"} -protocol-triple = {path="./protocol/triple"} -registry-zookeeper = {path="./registry/zookeeper"} -registry-nacos = {path="./registry/nacos"} +logger = { path = "./common/logger" } +utils = { path = "./common/utils" } +base = { path = "./common/base" } +config = { path = "./config" } +remoting-net = { path = "./remoting/net" } +protocol = { path = "protocol/base" } +protocol-dubbo2 = { path = "./protocol/dubbo2" } +protocol-triple = { path = "./protocol/triple" } +registry-zookeeper = { path = "./registry/zookeeper" } +registry-nacos = { path = "./registry/nacos" } anyhow = "1.0.66" dubbo = { path = "./dubbo/" } bb8 = "0.8.0" # A connecton pool based on tokio @@ -59,5 +59,5 @@ itertools = "0.10.1" ctor = "0.1.23" getset = "0.1.2" thiserror = "1.0.29" - +validator = "0.15" diff --git a/common/base/src/constants.rs b/common/base/src/constants.rs index ee2876b2..a470a51a 100644 --- a/common/base/src/constants.rs +++ b/common/base/src/constants.rs @@ -34,6 +34,7 @@ pub const TIMESTAMP_KEY: &str = "timestamp"; pub const DEFAULT_CONFIG_FILE: &str = "dubbo.yaml"; // env keys - pub const ENV_DUBBO_CONFIG_PATH: &str = "DUBBO_CONFIG_PATH"; pub const ENV_DUBBO_CONFIG_FILE: &str = "DUBBO_CONFIG_FILE"; + +// config keys diff --git a/config/src/types/consumer.rs b/config/src/types/consumer.rs index 3f8e8c80..1e8efedc 100644 --- a/config/src/types/consumer.rs +++ b/config/src/types/consumer.rs @@ -15,11 +15,13 @@ * limitations under the License. */ +use anyhow::Error; use std::collections::HashMap; use serde::Deserialize; use serde::Serialize; +use crate::types::ConfigValidator; use base::types::alias::{ ClusterStrategy, FilterKey, GroupId, InterfaceName, ParamKey, ProtocolKey, RegistryId, ServiceName, @@ -32,7 +34,7 @@ pub struct ConsumerConfig { #[serde(default)] pub filter: FilterKey, #[serde(default)] - pub protocol_ids: Vec, + pub protocol_ids: String, #[serde(default)] pub references: ReferenceConfig, } @@ -58,3 +60,9 @@ pub struct Reference { #[serde(default)] pub retries: String, } + +impl ConfigValidator for Reference { + fn validate(&self) -> Result<(), Error> { + todo!() + } +} diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index 5eb1ba43..0e585240 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -22,6 +22,7 @@ use crate::types::provider::ProviderConfig; use crate::types::registry::RegistryConfig; use crate::types::services::ServicesConfig; use crate::util::yaml_file_parser; +use anyhow::Error; use base::constants::DUBBO_KEY; use getset::{CopyGetters, Getters, MutGetters, Setters}; use serde::Deserialize; @@ -84,3 +85,7 @@ impl ConfigWrapper { ConfigWrapper { inner } } } + +pub trait ConfigValidator { + fn validate(&self) -> Result<(), Error>; +} diff --git a/config/src/types/protocol.rs b/config/src/types/protocol.rs index caa9620a..435ab813 100644 --- a/config/src/types/protocol.rs +++ b/config/src/types/protocol.rs @@ -17,9 +17,13 @@ use std::collections::HashMap; -use base::types::alias::{ParamKey, Port, ProtocolKey}; +use anyhow::Error; use serde::{Deserialize, Serialize}; +use base::types::alias::{ParamKey, Port, ProtocolKey}; + +use crate::types::ConfigValidator; + #[derive(Default, Debug, Clone, Serialize, Deserialize)] pub struct Protocol { #[serde(default)] @@ -34,3 +38,9 @@ pub struct Protocol { } pub type ProtocolConfig = HashMap; + +impl ConfigValidator for Protocol { + fn validate(&self) -> Result<(), Error> { + todo!() + } +} diff --git a/config/src/types/registry.rs b/config/src/types/registry.rs index cf9e17c0..82f91fc2 100644 --- a/config/src/types/registry.rs +++ b/config/src/types/registry.rs @@ -14,12 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use anyhow::Error; use std::collections::HashMap; use serde::{Deserialize, Serialize}; +use crate::types::ConfigValidator; use base::types::alias::{ParamKey, RegistryId, RegistryType}; - pub type RegistryConfig = HashMap; #[derive(Debug, Default, Serialize, Deserialize, Clone)] @@ -39,3 +40,9 @@ pub struct Registry { #[serde(default)] pub registry_type: RegistryType, } + +impl ConfigValidator for Registry { + fn validate(&self) -> Result<(), Error> { + todo!() + } +} diff --git a/config/src/types/services.rs b/config/src/types/services.rs index 50084373..8f7d0c7d 100644 --- a/config/src/types/services.rs +++ b/config/src/types/services.rs @@ -15,6 +15,8 @@ * limitations under the License. */ +use crate::types::ConfigValidator; +use anyhow::Error; use base::types::alias::{ GroupId, InterfaceName, ProtocolKey, SerializationKey, ServiceName, Version, }; @@ -36,3 +38,9 @@ pub struct Service { #[serde(default)] pub serialization: SerializationKey, } + +impl ConfigValidator for Service { + fn validate(&self) -> Result<(), Error> { + todo!() + } +} diff --git a/config/tests/dubbo.yaml b/config/tests/dubbo.yaml index ec3897e2..48dbd897 100644 --- a/config/tests/dubbo.yaml +++ b/config/tests/dubbo.yaml @@ -17,7 +17,9 @@ dubbo: protocol: zookeeper address: 0.0.0.0:2181 provider: - registry_ids: zk + registry_ids: + - zk + - demoZK services: UserProvider: serialization: hessian2 @@ -36,7 +38,8 @@ dubbo: retries: 5 services: "UserProvider": - registry_ids: "demoZk" + registry_ids: + - demoZk protocol: "dubbo" interface: "org.apache.dubbo.UserProvider" loadbalance: "random" diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 7aa2a9f5..89dcbb9f 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -25,6 +25,7 @@ mod tests_api { use config::api::ConfigApi; use config::get_root_config; use config::location::set_config_file_path; + use config::types::registry::Registry; static INIT: Once = Once::new(); @@ -65,4 +66,10 @@ mod tests_api { assert_eq!(new_config.port, "111".to_string()); assert_eq!(new_config.name, "dubbo".to_string()); } + + #[test] + fn test_registry_config() { + let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK").unwrap(); + assert_eq!("zookeeper".to_string(), zk_config.protocol) + } } From 3f7c874e3dcb5340f1a98d7daaa1dead0594da71 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 09:15:28 +0800 Subject: [PATCH 33/52] Ftr: config api --- common/base/src/types/alias.rs | 2 +- common/utils/src/host_util.rs | 6 +++--- config/src/types/consumer.rs | 5 +++-- config/src/types/default.rs | 39 ++++++++++++++++++++++++++++++++++ config/src/types/mod.rs | 1 + config/src/types/protocol.rs | 3 ++- config/src/types/registry.rs | 3 ++- config/src/types/services.rs | 9 ++++---- 8 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 config/src/types/default.rs diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs index 50c30fa4..c64cb1c5 100644 --- a/common/base/src/types/alias.rs +++ b/common/base/src/types/alias.rs @@ -26,7 +26,7 @@ pub type SerializationKey = String; // pub type ProtocolKey = String; pub type GroupId = String; -pub type Version = String; +pub type VersionNumber = String; pub type InterfaceName = String; diff --git a/common/utils/src/host_util.rs b/common/utils/src/host_util.rs index 0b029ef8..fba432e6 100644 --- a/common/utils/src/host_util.rs +++ b/common/utils/src/host_util.rs @@ -22,18 +22,18 @@ pub use port_selector::Port; // get local ip for linux/macos/windows #[allow(dead_code)] -pub(crate) fn local_ip() -> IpAddr { +pub fn local_ip() -> IpAddr { local_ip_address::local_ip().unwrap() } #[allow(dead_code)] -pub(crate) fn is_free_port(port: Port) -> bool { +pub fn is_free_port(port: Port) -> bool { is_free(port) } // scan from the give port #[allow(dead_code)] -pub(crate) fn scan_free_port(port: Port) -> Port { +pub fn scan_free_port(port: Port) -> Port { for selected_port in port..65535 { if is_free_port(selected_port) { return selected_port; diff --git a/config/src/types/consumer.rs b/config/src/types/consumer.rs index 1e8efedc..9ae0eac7 100644 --- a/config/src/types/consumer.rs +++ b/config/src/types/consumer.rs @@ -21,6 +21,7 @@ use std::collections::HashMap; use serde::Deserialize; use serde::Serialize; +use crate::types::default::*; use crate::types::ConfigValidator; use base::types::alias::{ ClusterStrategy, FilterKey, GroupId, InterfaceName, ParamKey, ProtocolKey, RegistryId, @@ -47,7 +48,7 @@ pub struct Reference { pub url: String, #[serde(default)] pub protocol: ProtocolKey, - #[serde(default)] + #[serde(default = "default_group_id")] pub group: GroupId, #[serde(default)] pub interface: InterfaceName, @@ -57,7 +58,7 @@ pub struct Reference { pub cluster: ClusterStrategy, #[serde(default)] pub params: HashMap, - #[serde(default)] + #[serde(default = "default_retries")] pub retries: String, } diff --git a/config/src/types/default.rs b/config/src/types/default.rs new file mode 100644 index 00000000..5d5cb5d3 --- /dev/null +++ b/config/src/types/default.rs @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +use base::types::alias::{GroupId, VersionNumber}; +use utils::host_util; + +pub fn default_group_id() -> GroupId { + "default".to_string() +} + +pub fn default_version_number() -> VersionNumber { + "0.1.0".to_string() +} + +pub fn default_retries() -> String { + "3".to_string() +} + +pub fn localhost() -> String { + host_util::local_ip().to_string() +} + +pub fn default_timeout() -> String { + "3000".to_string() +} diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index 0e585240..9c50cf0e 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -32,6 +32,7 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex}; pub mod consumer; +pub mod default; pub mod protocol; pub mod provider; pub mod registry; diff --git a/config/src/types/protocol.rs b/config/src/types/protocol.rs index 435ab813..ee62f274 100644 --- a/config/src/types/protocol.rs +++ b/config/src/types/protocol.rs @@ -17,6 +17,7 @@ use std::collections::HashMap; +use crate::types::default::localhost; use anyhow::Error; use serde::{Deserialize, Serialize}; @@ -28,7 +29,7 @@ use crate::types::ConfigValidator; pub struct Protocol { #[serde(default)] pub ip: String, - #[serde(default)] + #[serde(default = "localhost")] pub port: Port, #[serde(default)] pub name: ProtocolKey, diff --git a/config/src/types/registry.rs b/config/src/types/registry.rs index 82f91fc2..a0eb363a 100644 --- a/config/src/types/registry.rs +++ b/config/src/types/registry.rs @@ -17,6 +17,7 @@ use anyhow::Error; use std::collections::HashMap; +use crate::types::default::default_timeout; use serde::{Deserialize, Serialize}; use crate::types::ConfigValidator; @@ -27,7 +28,7 @@ pub type RegistryConfig = HashMap; pub struct Registry { #[serde(default)] pub protocol: RegistryId, - #[serde(default)] + #[serde(default = "default_timeout")] pub timeout: String, #[serde(default)] pub address: String, diff --git a/config/src/types/services.rs b/config/src/types/services.rs index 8f7d0c7d..8c46fce6 100644 --- a/config/src/types/services.rs +++ b/config/src/types/services.rs @@ -15,10 +15,11 @@ * limitations under the License. */ +use crate::types::default::*; use crate::types::ConfigValidator; use anyhow::Error; use base::types::alias::{ - GroupId, InterfaceName, ProtocolKey, SerializationKey, ServiceName, Version, + GroupId, InterfaceName, ProtocolKey, SerializationKey, ServiceName, VersionNumber, }; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -27,9 +28,9 @@ pub type ServicesConfig = HashMap; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct Service { - #[serde(default)] - pub version: Version, - #[serde(default)] + #[serde(default = "default_version_number")] + pub version: VersionNumber, + #[serde(default = "default_group_id")] pub group: GroupId, #[serde(default)] pub protocol: ProtocolKey, From 7f0c7f072ba2b8bd1a53744a9c9ab742f97c0edf Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 09:34:50 +0800 Subject: [PATCH 34/52] Ftr: config api --- common/base/Cargo.toml | 3 +- common/base/src/types/error.rs | 16 ++++++++ common/base/src/types/mod.rs | 1 + config/src/api.rs | 73 ++++++++++++++-------------------- config/tests/test_api.rs | 38 +++++++++--------- 5 files changed, 68 insertions(+), 63 deletions(-) create mode 100644 common/base/src/types/error.rs diff --git a/common/base/Cargo.toml b/common/base/Cargo.toml index 9996de2c..3293c4eb 100644 --- a/common/base/Cargo.toml +++ b/common/base/Cargo.toml @@ -8,4 +8,5 @@ edition = "2021" [dependencies] urlencoding.workspace = true http = "0.2" -tracing.workspace=true \ No newline at end of file +tracing.workspace=true +anyhow.workspace = true \ No newline at end of file diff --git a/common/base/src/types/error.rs b/common/base/src/types/error.rs new file mode 100644 index 00000000..2944f981 --- /dev/null +++ b/common/base/src/types/error.rs @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ diff --git a/common/base/src/types/mod.rs b/common/base/src/types/mod.rs index 8e8b88c7..6356be89 100644 --- a/common/base/src/types/mod.rs +++ b/common/base/src/types/mod.rs @@ -15,3 +15,4 @@ * limitations under the License. */ pub mod alias; +pub mod error; diff --git a/config/src/api.rs b/config/src/api.rs index ef563546..c7bd6845 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -29,41 +29,31 @@ use crate::ConfigWrapper; // could be used for config_center pub trait ConfigApi { - fn dubbo_protocol_set(&self, protocol: &str, key: String, value: String) -> Result<(), Error>; + fn dubbo_protocol_set(&self, protocol: &str, key: &str, value: &str) -> Result<(), Error>; fn dubbo_protocol_get(&self, protocol: &str) -> Result; fn dubbo_registry_get(&self, registry_id: &str) -> Result; - fn dubbo_registry_set( - &self, - registry_id: &str, - key: String, - value: String, - ) -> Result<(), Error>; + fn dubbo_registry_set(&self, registry_id: &str, key: &str, value: &str) -> Result<(), Error>; fn dubbo_services_get(&self, service_name: &str) -> Result; - fn dubbo_services_set( - &self, - service_name: &str, - key: String, - value: String, - ) -> Result<(), Error>; + fn dubbo_services_set(&self, service_name: &str, key: &str, value: &str) -> Result<(), Error>; fn dubbo_provider_services_get(&self, service_name: &str) -> Result; fn dubbo_provider_services_set( &self, service_name: &str, - key: String, - value: String, + key: &str, + value: &str, ) -> Result<(), Error>; fn dubbo_consumer_references_get(&self, service_name: &str) -> Result; fn dubbo_consumer_references_set( &self, service_name: &str, - key: String, - value: String, + key: &str, + value: &str, ) -> Result<(), Error>; } impl ConfigApi for ConfigWrapper { - fn dubbo_protocol_set(&self, protocol: &str, key: String, value: String) -> Result<(), Error> { + fn dubbo_protocol_set(&self, protocol: &str, key: &str, value: &str) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.protocols.contains_key(protocol) { guard @@ -71,12 +61,13 @@ impl ConfigApi for ConfigWrapper { .insert(protocol.to_string(), Protocol::default()); } let x = guard.protocols.get_mut(protocol).unwrap(); - match key.as_str() { + let value = value.to_string(); + match key { "ip" => x.ip = value, "port" => x.port = value, "name" => x.name = value, _ => { - HashMap::insert(&mut x.params, key, value); + HashMap::insert(&mut x.params, key.to_string(), value); } } Ok(()) @@ -100,12 +91,7 @@ impl ConfigApi for ConfigWrapper { Ok(guard.registries.get(registry_id).unwrap().clone()) } - fn dubbo_registry_set( - &self, - registry_id: &str, - key: String, - value: String, - ) -> Result<(), Error> { + fn dubbo_registry_set(&self, registry_id: &str, key: &str, value: &str) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.registries.contains_key(registry_id) { guard @@ -113,7 +99,8 @@ impl ConfigApi for ConfigWrapper { .insert(registry_id.to_string(), Registry::default()); } let x = guard.registries.get_mut(registry_id).unwrap(); - match key.as_str() { + let value = value.to_string(); + match key { "protocol" => x.protocol = value, "registry_type" => x.registry_type = value, "address" => x.address = value, @@ -121,7 +108,7 @@ impl ConfigApi for ConfigWrapper { "username" => x.username = value, "timeout" => x.timeout = value, _ => { - HashMap::insert(&mut x.params, key, value); + HashMap::insert(&mut x.params, key.to_string(), value); } } Ok(()) @@ -137,12 +124,7 @@ impl ConfigApi for ConfigWrapper { Ok(guard.services.get(service_name).unwrap().clone()) } - fn dubbo_services_set( - &self, - service_name: &str, - key: String, - value: String, - ) -> Result<(), Error> { + fn dubbo_services_set(&self, service_name: &str, key: &str, value: &str) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.services.contains_key(service_name) { guard @@ -150,7 +132,8 @@ impl ConfigApi for ConfigWrapper { .insert(service_name.to_string(), Service::default()); } let x = guard.services.get_mut(service_name).unwrap(); - match key.as_str() { + let value = value.to_string(); + match key { "protocol" => x.protocol = value, "interface" => x.interface = value, "group" => x.group = value, @@ -159,7 +142,7 @@ impl ConfigApi for ConfigWrapper { _ => { return Err(anyhow!(ConfigError::UnsupportedKey( "services".to_string(), - key + key.to_string() ))); } } @@ -179,8 +162,8 @@ impl ConfigApi for ConfigWrapper { fn dubbo_provider_services_set( &self, service_name: &str, - key: String, - value: String, + key: &str, + value: &str, ) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.provider.services.contains_key(service_name) { @@ -189,7 +172,8 @@ impl ConfigApi for ConfigWrapper { .insert(service_name.to_string(), Service::default()); } let x = guard.provider.services.get_mut(service_name).unwrap(); - match key.as_str() { + let value = value.to_string(); + match key { "protocol" => x.protocol = value, "interface" => x.interface = value, "group" => x.group = value, @@ -198,7 +182,7 @@ impl ConfigApi for ConfigWrapper { _ => { return Err(anyhow!(ConfigError::UnsupportedKey( "provider.services".to_string(), - key + key.to_string() ))); } } @@ -218,8 +202,8 @@ impl ConfigApi for ConfigWrapper { fn dubbo_consumer_references_set( &self, service_name: &str, - key: String, - value: String, + key: &str, + value: &str, ) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.consumer.references.contains_key(service_name) { @@ -228,7 +212,8 @@ impl ConfigApi for ConfigWrapper { .insert(service_name.to_string(), Service::default()); } let x = guard.consumer.references.get_mut(service_name).unwrap(); - match key.as_str() { + let value = value.to_string(); + match key { "protocol" => x.protocol = value, "interface" => x.interface = value, "group" => x.group = value, @@ -239,7 +224,7 @@ impl ConfigApi for ConfigWrapper { _ => { return Err(anyhow!(ConfigError::UnsupportedKey( "consumer.references".to_string(), - key + key.to_string() ))); } } diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 89dcbb9f..2b9ab642 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -17,6 +17,7 @@ #[cfg(test)] mod tests_api { + use anyhow::Error; use std::env; use std::sync::Once; @@ -46,30 +47,31 @@ mod tests_api { } #[test] - fn test_dubbo_protocol_set_overwrite_yaml_by_api() { + fn test_dubbo_protocol_set_overwrite_yaml_by_api() -> Result<(), Error> { let config_wrapper = get_root_config(); - let old_config = config_wrapper.dubbo_protocol_get("dubbo").unwrap(); + let old_config = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(old_config.port, "8888".to_string()); - config_wrapper - .dubbo_protocol_set("dubbo", "ip".to_string(), "122.22.22.22".to_string()) - .unwrap(); - config_wrapper - .dubbo_protocol_set("dubbo", "port".to_string(), "111".to_string()) - .unwrap(); - config_wrapper - .dubbo_protocol_set("dubbo", "name".to_string(), "dubbo".to_string()) - .unwrap(); - config_wrapper - .dubbo_protocol_set("dubbo", "nam1e".to_string(), "dubbo".to_string()) - .unwrap(); - let new_config = config_wrapper.dubbo_protocol_get("dubbo").unwrap(); + config_wrapper.dubbo_protocol_set("dubbo", "ip", "122.22.22.22")?; + config_wrapper.dubbo_protocol_set("dubbo", "port", "111")?; + config_wrapper.dubbo_protocol_set("dubbo", "name", "dubbo")?; + config_wrapper.dubbo_protocol_set("dubbo", "nam1e", "dubbo")?; + let new_config = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(new_config.port, "111".to_string()); assert_eq!(new_config.name, "dubbo".to_string()); + Ok(()) } #[test] - fn test_registry_config() { - let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK").unwrap(); - assert_eq!("zookeeper".to_string(), zk_config.protocol) + fn test_registry_config() -> Result<(), Error> { + let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK")?; + assert_eq!("zookeeper", zk_config.protocol); + Ok(()) + } + + #[test] + fn test_default_value() -> Result<(), Error> { + let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK")?; + assert_eq!("3000", zk_config.timeout); + Ok(()) } } From 4599463d0b0d5661d632bca0c6ab894b758e5a4a Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 09:37:17 +0800 Subject: [PATCH 35/52] Ftr: config api --- config/tests/test_api.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 2b9ab642..86feb4ef 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -26,6 +26,7 @@ mod tests_api { use config::api::ConfigApi; use config::get_root_config; use config::location::set_config_file_path; + use config::types::protocol::Protocol; use config::types::registry::Registry; static INIT: Once = Once::new(); @@ -55,9 +56,13 @@ mod tests_api { config_wrapper.dubbo_protocol_set("dubbo", "port", "111")?; config_wrapper.dubbo_protocol_set("dubbo", "name", "dubbo")?; config_wrapper.dubbo_protocol_set("dubbo", "nam1e", "dubbo")?; - let new_config = config_wrapper.dubbo_protocol_get("dubbo")?; + let new_config: Protocol = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(new_config.port, "111".to_string()); assert_eq!(new_config.name, "dubbo".to_string()); + assert_eq!( + new_config.params.get("nam1e").unwrap().clone(), + "dubbo".to_string() + ); Ok(()) } From 51d1b44afd6e2eec3e068a92f2cea0ebafe123d4 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 09:43:30 +0800 Subject: [PATCH 36/52] Ftr: config api --- common/base/src/types/alias.rs | 1 + config/src/types/protocol.rs | 8 ++--- config/src/types/provider.rs | 5 +-- config/tests/test_use_root_dir.rs | 60 +++++++++++++++++++++++++++++++ dubbo.yaml | 3 ++ 5 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 config/tests/test_use_root_dir.rs diff --git a/common/base/src/types/alias.rs b/common/base/src/types/alias.rs index c64cb1c5..6beb6c2b 100644 --- a/common/base/src/types/alias.rs +++ b/common/base/src/types/alias.rs @@ -24,6 +24,7 @@ pub type ServiceName = String; pub type ServiceKey = String; pub type SerializationKey = String; // +pub type ProtocolId = String; pub type ProtocolKey = String; pub type GroupId = String; pub type VersionNumber = String; diff --git a/config/src/types/protocol.rs b/config/src/types/protocol.rs index ee62f274..40c499be 100644 --- a/config/src/types/protocol.rs +++ b/config/src/types/protocol.rs @@ -21,15 +21,15 @@ use crate::types::default::localhost; use anyhow::Error; use serde::{Deserialize, Serialize}; -use base::types::alias::{ParamKey, Port, ProtocolKey}; +use base::types::alias::{ParamKey, Port, ProtocolId, ProtocolKey}; use crate::types::ConfigValidator; #[derive(Default, Debug, Clone, Serialize, Deserialize)] pub struct Protocol { - #[serde(default)] - pub ip: String, #[serde(default = "localhost")] + pub ip: String, + #[serde(default)] pub port: Port, #[serde(default)] pub name: ProtocolKey, @@ -38,7 +38,7 @@ pub struct Protocol { pub params: HashMap, } -pub type ProtocolConfig = HashMap; +pub type ProtocolConfig = HashMap; impl ConfigValidator for Protocol { fn validate(&self) -> Result<(), Error> { diff --git a/config/src/types/provider.rs b/config/src/types/provider.rs index 35946717..70b4b8e4 100644 --- a/config/src/types/provider.rs +++ b/config/src/types/provider.rs @@ -16,14 +16,15 @@ */ use crate::types::services::ServicesConfig; +use base::types::alias::{ProtocolId, RegistryId}; use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct ProviderConfig { #[serde(default)] - pub registry_ids: Vec, + pub registry_ids: Vec, #[serde(default)] - pub protocol_ids: Vec, + pub protocol_ids: Vec, #[serde(default)] pub services: ServicesConfig, } diff --git a/config/tests/test_use_root_dir.rs b/config/tests/test_use_root_dir.rs new file mode 100644 index 00000000..0c1664ba --- /dev/null +++ b/config/tests/test_use_root_dir.rs @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +#[cfg(test)] +mod tests_api { + use anyhow::Error; + + use config::api::ConfigApi; + use config::get_root_config; + use config::types::protocol::Protocol; + use config::types::registry::Registry; + + #[test] + fn test_dubbo_protocol_set_overwrite_yaml_by_api() -> Result<(), Error> { + let config_wrapper = get_root_config(); + let old_config: Protocol = config_wrapper.dubbo_protocol_get("dubbo")?; + assert_eq!(old_config.port, "8888"); + println!("{}", old_config.ip); + config_wrapper.dubbo_protocol_set("dubbo", "ip", "122.22.22.22")?; + config_wrapper.dubbo_protocol_set("dubbo", "port", "111")?; + config_wrapper.dubbo_protocol_set("dubbo", "name", "dubbo")?; + config_wrapper.dubbo_protocol_set("dubbo", "nam1e", "dubbo")?; + let new_config: Protocol = config_wrapper.dubbo_protocol_get("dubbo")?; + assert_eq!(new_config.port, "111".to_string()); + assert_eq!(new_config.name, "dubbo".to_string()); + assert_eq!( + new_config.params.get("nam1e").unwrap().clone(), + "dubbo".to_string() + ); + Ok(()) + } + + #[test] + fn test_registry_config() -> Result<(), Error> { + let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK")?; + assert_eq!("zookeeper", zk_config.protocol); + Ok(()) + } + + #[test] + fn test_default_value() -> Result<(), Error> { + let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK")?; + assert_eq!("3000", zk_config.timeout); + Ok(()) + } +} diff --git a/dubbo.yaml b/dubbo.yaml index d357db14..2a294ad0 100644 --- a/dubbo.yaml +++ b/dubbo.yaml @@ -6,6 +6,9 @@ dubbo: ip: 0.0.0.0 port: '8888' name: tri + dubbo: + port: 8888 + name: dubbo registries: demoZK: protocol: zookeeper From b17e2b3ffc46a640713d96139d253311e0990a02 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 09:52:27 +0800 Subject: [PATCH 37/52] Ftr: config api --- config/tests/dubbo.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tests/dubbo.yaml b/config/tests/dubbo.yaml index 48dbd897..ddc876eb 100644 --- a/config/tests/dubbo.yaml +++ b/config/tests/dubbo.yaml @@ -11,7 +11,7 @@ dubbo: dubbo: ip: 0.0.0.0 port: 8888 - name: tri + name: dubbo registries: demoZK: protocol: zookeeper From 15cdb6630d6b4f58b120634bd0f6b52db5739bce Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 10:00:27 +0800 Subject: [PATCH 38/52] Ftr: config api --- common/base/src/constants.rs | 3 +++ config/src/types/default.rs | 11 ++++++++++- config/src/types/protocol.rs | 4 ++-- config/src/types/registry.rs | 6 +++--- config/src/types/services.rs | 4 ++-- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/common/base/src/constants.rs b/common/base/src/constants.rs index a470a51a..bb3ff3f9 100644 --- a/common/base/src/constants.rs +++ b/common/base/src/constants.rs @@ -18,6 +18,9 @@ pub const REGISTRY_PROTOCOL: &str = "registry_protocol"; pub const PROTOCOL: &str = "protocol"; pub const REGISTRY: &str = "registry"; +pub const REGISTRY_TYPE_SERVICE: &str = "service"; +pub const REGISTRY_TYPE_APPLICATION: &str = "application"; + // URL key pub const DUBBO_KEY: &str = "dubbo"; pub const PROVIDERS_KEY: &str = "providers"; diff --git a/config/src/types/default.rs b/config/src/types/default.rs index 5d5cb5d3..b3614091 100644 --- a/config/src/types/default.rs +++ b/config/src/types/default.rs @@ -15,7 +15,8 @@ * limitations under the License. */ -use base::types::alias::{GroupId, VersionNumber}; +use base::constants::REGISTRY_TYPE_SERVICE; +use base::types::alias::{GroupId, RegistryType, VersionNumber}; use utils::host_util; pub fn default_group_id() -> GroupId { @@ -37,3 +38,11 @@ pub fn localhost() -> String { pub fn default_timeout() -> String { "3000".to_string() } + +pub fn default_port() -> String { + host_util::scan_free_port(28000).to_string() +} + +pub fn default_registry_type() -> Vec { + vec![REGISTRY_TYPE_SERVICE.to_string()] +} diff --git a/config/src/types/protocol.rs b/config/src/types/protocol.rs index 40c499be..f100935e 100644 --- a/config/src/types/protocol.rs +++ b/config/src/types/protocol.rs @@ -17,7 +17,7 @@ use std::collections::HashMap; -use crate::types::default::localhost; +use crate::types::default::*; use anyhow::Error; use serde::{Deserialize, Serialize}; @@ -29,7 +29,7 @@ use crate::types::ConfigValidator; pub struct Protocol { #[serde(default = "localhost")] pub ip: String, - #[serde(default)] + #[serde(default = "default_port")] pub port: Port, #[serde(default)] pub name: ProtocolKey, diff --git a/config/src/types/registry.rs b/config/src/types/registry.rs index a0eb363a..fd1ad384 100644 --- a/config/src/types/registry.rs +++ b/config/src/types/registry.rs @@ -17,7 +17,7 @@ use anyhow::Error; use std::collections::HashMap; -use crate::types::default::default_timeout; +use crate::types::default::*; use serde::{Deserialize, Serialize}; use crate::types::ConfigValidator; @@ -38,8 +38,8 @@ pub struct Registry { pub password: String, #[serde(default)] pub params: HashMap, - #[serde(default)] - pub registry_type: RegistryType, + #[serde(default = "default_registry_type")] + pub registry_type: Vec, } impl ConfigValidator for Registry { diff --git a/config/src/types/services.rs b/config/src/types/services.rs index 8c46fce6..f27dc853 100644 --- a/config/src/types/services.rs +++ b/config/src/types/services.rs @@ -19,7 +19,7 @@ use crate::types::default::*; use crate::types::ConfigValidator; use anyhow::Error; use base::types::alias::{ - GroupId, InterfaceName, ProtocolKey, SerializationKey, ServiceName, VersionNumber, + GroupId, InterfaceName, ProtocolId, ProtocolKey, SerializationKey, ServiceName, VersionNumber, }; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -33,7 +33,7 @@ pub struct Service { #[serde(default = "default_group_id")] pub group: GroupId, #[serde(default)] - pub protocol: ProtocolKey, + pub protocol: ProtocolId, #[serde(default)] pub interface: InterfaceName, #[serde(default)] From 623dee50253ccb04ade91340275ac7ba6bbd29e5 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 10:03:16 +0800 Subject: [PATCH 39/52] Ftr: config api --- config/src/api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/src/api.rs b/config/src/api.rs index c7bd6845..b69bae3e 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -102,7 +102,7 @@ impl ConfigApi for ConfigWrapper { let value = value.to_string(); match key { "protocol" => x.protocol = value, - "registry_type" => x.registry_type = value, + "registry_type" => x.registry_type = value.split(",").map(|x| x.to_string()).collect(), "address" => x.address = value, "password" => x.password = value, "username" => x.username = value, From 152fb63f7fea99e0566fd66d1db14588161c5508 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 10:19:04 +0800 Subject: [PATCH 40/52] Ftr: config api --- config/src/api.rs | 26 ++++++++++++++++++++++++++ config/src/types/services.rs | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/config/src/api.rs b/config/src/api.rs index b69bae3e..70189c46 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -19,6 +19,7 @@ use std::collections::HashMap; use crate::error::ConfigError; use anyhow::{anyhow, Error, Result}; +use base::types::alias::ServiceName; use crate::types::consumer::Reference; use crate::types::protocol::Protocol; @@ -31,10 +32,13 @@ use crate::ConfigWrapper; pub trait ConfigApi { fn dubbo_protocol_set(&self, protocol: &str, key: &str, value: &str) -> Result<(), Error>; fn dubbo_protocol_get(&self, protocol: &str) -> Result; + fn dubbo_registry_ids(&self) -> Option>; fn dubbo_registry_get(&self, registry_id: &str) -> Result; fn dubbo_registry_set(&self, registry_id: &str, key: &str, value: &str) -> Result<(), Error>; + fn dubbo_services_name(&self) -> Option>; fn dubbo_services_get(&self, service_name: &str) -> Result; fn dubbo_services_set(&self, service_name: &str, key: &str, value: &str) -> Result<(), Error>; + fn dubbo_provider_services_name(&self) -> Option>; fn dubbo_provider_services_get(&self, service_name: &str) -> Result; fn dubbo_provider_services_set( &self, @@ -81,6 +85,11 @@ impl ConfigApi for ConfigWrapper { Ok(guard.protocols.get(protocol).unwrap().clone()) } + fn dubbo_registry_ids(&self) -> Option> { + let guard = self.inner.lock().unwrap(); + Some(guard.registries.keys().map(|x| x.to_string()).collect()) + } + fn dubbo_registry_get(&self, registry_id: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.registries.contains_key(registry_id) { @@ -114,6 +123,11 @@ impl ConfigApi for ConfigWrapper { Ok(()) } + fn dubbo_services_name(&self) -> Option> { + let guard = self.inner.lock().unwrap(); + Some(guard.services.keys().map(|x| x.to_string()).collect()) + } + fn dubbo_services_get(&self, service_name: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.services.contains_key(service_name) { @@ -149,6 +163,18 @@ impl ConfigApi for ConfigWrapper { Ok(()) } + fn dubbo_provider_services_name(&self) -> Option> { + let guard = self.inner.lock().unwrap(); + Some( + guard + .provider + .services + .keys() + .map(|x| x.to_string()) + .collect(), + ) + } + fn dubbo_provider_services_get(&self, service_name: &str) -> Result { let guard = self.inner.lock().unwrap(); if !guard.services.contains_key(service_name) { diff --git a/config/src/types/services.rs b/config/src/types/services.rs index f27dc853..96128636 100644 --- a/config/src/types/services.rs +++ b/config/src/types/services.rs @@ -19,7 +19,7 @@ use crate::types::default::*; use crate::types::ConfigValidator; use anyhow::Error; use base::types::alias::{ - GroupId, InterfaceName, ProtocolId, ProtocolKey, SerializationKey, ServiceName, VersionNumber, + GroupId, InterfaceName, ProtocolId, SerializationKey, ServiceName, VersionNumber, }; use serde::{Deserialize, Serialize}; use std::collections::HashMap; From 57277a478984ecf805e892a97991e0c728474bad Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 11:03:49 +0800 Subject: [PATCH 41/52] Ftr: config api --- config/src/api.rs | 158 +++++++++++++++++------------- config/tests/test_api.rs | 13 ++- config/tests/test_use_root_dir.rs | 13 ++- 3 files changed, 107 insertions(+), 77 deletions(-) diff --git a/config/src/api.rs b/config/src/api.rs index 70189c46..2a10c9c5 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -30,34 +30,33 @@ use crate::ConfigWrapper; // could be used for config_center pub trait ConfigApi { - fn dubbo_protocol_set(&self, protocol: &str, key: &str, value: &str) -> Result<(), Error>; + fn dubbo_protocol_set(&self, protocol: &str, pairs: Vec<(&str, &str)>) -> Result<(), Error>; fn dubbo_protocol_get(&self, protocol: &str) -> Result; fn dubbo_registry_ids(&self) -> Option>; fn dubbo_registry_get(&self, registry_id: &str) -> Result; - fn dubbo_registry_set(&self, registry_id: &str, key: &str, value: &str) -> Result<(), Error>; + fn dubbo_registry_set(&self, registry_id: &str, pairs: Vec<(&str, &str)>) -> Result<(), Error>; fn dubbo_services_name(&self) -> Option>; fn dubbo_services_get(&self, service_name: &str) -> Result; - fn dubbo_services_set(&self, service_name: &str, key: &str, value: &str) -> Result<(), Error>; + fn dubbo_services_set(&self, service_name: &str, pairs: Vec<(&str, &str)>) + -> Result<(), Error>; fn dubbo_provider_services_name(&self) -> Option>; fn dubbo_provider_services_get(&self, service_name: &str) -> Result; fn dubbo_provider_services_set( &self, service_name: &str, - key: &str, - value: &str, + pairs: Vec<(&str, &str)>, ) -> Result<(), Error>; fn dubbo_consumer_references_get(&self, service_name: &str) -> Result; fn dubbo_consumer_references_set( &self, service_name: &str, - key: &str, - value: &str, + pairs: Vec<(&str, &str)>, ) -> Result<(), Error>; } impl ConfigApi for ConfigWrapper { - fn dubbo_protocol_set(&self, protocol: &str, key: &str, value: &str) -> Result<(), Error> { + fn dubbo_protocol_set(&self, protocol: &str, pairs: Vec<(&str, &str)>) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.protocols.contains_key(protocol) { guard @@ -65,15 +64,18 @@ impl ConfigApi for ConfigWrapper { .insert(protocol.to_string(), Protocol::default()); } let x = guard.protocols.get_mut(protocol).unwrap(); - let value = value.to_string(); - match key { - "ip" => x.ip = value, - "port" => x.port = value, - "name" => x.name = value, - _ => { - HashMap::insert(&mut x.params, key.to_string(), value); + for pair in pairs { + let value = pair.1.to_string(); + match pair.0 { + "ip" => x.ip = value, + "port" => x.port = value, + "name" => x.name = value, + _ => { + HashMap::insert(&mut x.params, pair.0.to_string(), value); + } } } + Ok(()) } @@ -100,7 +102,7 @@ impl ConfigApi for ConfigWrapper { Ok(guard.registries.get(registry_id).unwrap().clone()) } - fn dubbo_registry_set(&self, registry_id: &str, key: &str, value: &str) -> Result<(), Error> { + fn dubbo_registry_set(&self, registry_id: &str, pairs: Vec<(&str, &str)>) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.registries.contains_key(registry_id) { guard @@ -108,18 +110,23 @@ impl ConfigApi for ConfigWrapper { .insert(registry_id.to_string(), Registry::default()); } let x = guard.registries.get_mut(registry_id).unwrap(); - let value = value.to_string(); - match key { - "protocol" => x.protocol = value, - "registry_type" => x.registry_type = value.split(",").map(|x| x.to_string()).collect(), - "address" => x.address = value, - "password" => x.password = value, - "username" => x.username = value, - "timeout" => x.timeout = value, - _ => { - HashMap::insert(&mut x.params, key.to_string(), value); + for pair in pairs { + let value = pair.1.to_string(); + match pair.0 { + "protocol" => x.protocol = value, + "registry_type" => { + x.registry_type = value.split(",").map(|x| x.to_string()).collect() + } + "address" => x.address = value, + "password" => x.password = value, + "username" => x.username = value, + "timeout" => x.timeout = value, + _ => { + HashMap::insert(&mut x.params, pair.0.to_string(), value); + } } } + Ok(()) } @@ -138,7 +145,11 @@ impl ConfigApi for ConfigWrapper { Ok(guard.services.get(service_name).unwrap().clone()) } - fn dubbo_services_set(&self, service_name: &str, key: &str, value: &str) -> Result<(), Error> { + fn dubbo_services_set( + &self, + service_name: &str, + pairs: Vec<(&str, &str)>, + ) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.services.contains_key(service_name) { guard @@ -146,20 +157,23 @@ impl ConfigApi for ConfigWrapper { .insert(service_name.to_string(), Service::default()); } let x = guard.services.get_mut(service_name).unwrap(); - let value = value.to_string(); - match key { - "protocol" => x.protocol = value, - "interface" => x.interface = value, - "group" => x.group = value, - "version" => x.version = value, - "serialization" => x.serialization = value, - _ => { - return Err(anyhow!(ConfigError::UnsupportedKey( - "services".to_string(), - key.to_string() - ))); + for pair in pairs { + let value = pair.1.to_string(); + match pair.0 { + "protocol" => x.protocol = value, + "interface" => x.interface = value, + "group" => x.group = value, + "version" => x.version = value, + "serialization" => x.serialization = value, + _ => { + return Err(anyhow!(ConfigError::UnsupportedKey( + "services".to_string(), + pair.0.to_string() + ))); + } } } + Ok(()) } @@ -188,8 +202,7 @@ impl ConfigApi for ConfigWrapper { fn dubbo_provider_services_set( &self, service_name: &str, - key: &str, - value: &str, + pairs: Vec<(&str, &str)>, ) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.provider.services.contains_key(service_name) { @@ -198,20 +211,23 @@ impl ConfigApi for ConfigWrapper { .insert(service_name.to_string(), Service::default()); } let x = guard.provider.services.get_mut(service_name).unwrap(); - let value = value.to_string(); - match key { - "protocol" => x.protocol = value, - "interface" => x.interface = value, - "group" => x.group = value, - "version" => x.version = value, - "serialization" => x.serialization = value, - _ => { - return Err(anyhow!(ConfigError::UnsupportedKey( - "provider.services".to_string(), - key.to_string() - ))); + for pair in pairs { + let value = pair.1.to_string(); + match pair.0 { + "protocol" => x.protocol = value, + "interface" => x.interface = value, + "group" => x.group = value, + "version" => x.version = value, + "serialization" => x.serialization = value, + _ => { + return Err(anyhow!(ConfigError::UnsupportedKey( + "provider.services".to_string(), + pair.0.to_string() + ))); + } } } + Ok(()) } @@ -228,8 +244,7 @@ impl ConfigApi for ConfigWrapper { fn dubbo_consumer_references_set( &self, service_name: &str, - key: &str, - value: &str, + pairs: Vec<(&str, &str)>, ) -> Result<(), Error> { let mut guard = self.inner.lock().unwrap(); if !guard.consumer.references.contains_key(service_name) { @@ -238,22 +253,27 @@ impl ConfigApi for ConfigWrapper { .insert(service_name.to_string(), Service::default()); } let x = guard.consumer.references.get_mut(service_name).unwrap(); - let value = value.to_string(); - match key { - "protocol" => x.protocol = value, - "interface" => x.interface = value, - "group" => x.group = value, - "cluster" => x.cluster = value, - "retries" => x.retries = value, - "url" => x.url = value, - "registry_ids" => x.registry_ids = value.split(',').map(|x| x.to_string()).collect(), - _ => { - return Err(anyhow!(ConfigError::UnsupportedKey( - "consumer.references".to_string(), - key.to_string() - ))); + for pair in pairs { + let value = pair.1.to_string(); + match pair.0 { + "protocol" => x.protocol = value, + "interface" => x.interface = value, + "group" => x.group = value, + "cluster" => x.cluster = value, + "retries" => x.retries = value, + "url" => x.url = value, + "registry_ids" => { + x.registry_ids = value.split(',').map(|x| x.to_string()).collect() + } + _ => { + return Err(anyhow!(ConfigError::UnsupportedKey( + "consumer.references".to_string(), + pair.0.to_string() + ))); + } } } + Ok(()) } } diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 86feb4ef..5d562688 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -52,10 +52,15 @@ mod tests_api { let config_wrapper = get_root_config(); let old_config = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(old_config.port, "8888".to_string()); - config_wrapper.dubbo_protocol_set("dubbo", "ip", "122.22.22.22")?; - config_wrapper.dubbo_protocol_set("dubbo", "port", "111")?; - config_wrapper.dubbo_protocol_set("dubbo", "name", "dubbo")?; - config_wrapper.dubbo_protocol_set("dubbo", "nam1e", "dubbo")?; + config_wrapper.dubbo_protocol_set( + "dubbo", + vec![ + ("ip", "122.22.22.22"), + ("port", "111"), + ("name", "dubbo"), + ("nam1e", "dubbo"), + ], + )?; let new_config: Protocol = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(new_config.port, "111".to_string()); assert_eq!(new_config.name, "dubbo".to_string()); diff --git a/config/tests/test_use_root_dir.rs b/config/tests/test_use_root_dir.rs index 0c1664ba..902dc102 100644 --- a/config/tests/test_use_root_dir.rs +++ b/config/tests/test_use_root_dir.rs @@ -30,10 +30,15 @@ mod tests_api { let old_config: Protocol = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(old_config.port, "8888"); println!("{}", old_config.ip); - config_wrapper.dubbo_protocol_set("dubbo", "ip", "122.22.22.22")?; - config_wrapper.dubbo_protocol_set("dubbo", "port", "111")?; - config_wrapper.dubbo_protocol_set("dubbo", "name", "dubbo")?; - config_wrapper.dubbo_protocol_set("dubbo", "nam1e", "dubbo")?; + config_wrapper.dubbo_protocol_set( + "dubbo", + vec![ + ("ip", "122.22.22.22"), + ("port", "111"), + ("name", "dubbo"), + ("nam1e", "dubbo"), + ], + )?; let new_config: Protocol = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(new_config.port, "111".to_string()); assert_eq!(new_config.name, "dubbo".to_string()); From c41788acd868f23b86818e5fad82d09e39dfeef0 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 12:02:00 +0800 Subject: [PATCH 42/52] Ftr: config api --- common/logger/src/tracing_configurer.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/common/logger/src/tracing_configurer.rs b/common/logger/src/tracing_configurer.rs index 654cfa32..5beb77b2 100644 --- a/common/logger/src/tracing_configurer.rs +++ b/common/logger/src/tracing_configurer.rs @@ -21,16 +21,13 @@ use crate::level::LevelWrapper; use config::util::yaml_key_reader; use std::path::PathBuf; use tracing::debug; -use tracing_subscriber::util; use utils::path_util; pub(crate) fn default() { let path_buf = PathBuf::new() .join(path_util::app_root_dir()) .join("../../../dubbo.yaml"); - let level: LevelWrapper = util::yaml_key_reader(path_buf, "logging.level") - .unwrap() - .into(); + let level: LevelWrapper = yaml_key_reader(path_buf, "logging.level").unwrap().into(); tracing_subscriber::fmt() .compact() .with_line_number(true) From a00c9a5854a112cadebbc5697e4b224e0bf43658 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 13:41:01 +0800 Subject: [PATCH 43/52] Ftr: config api --- Cargo.toml | 3 +++ dubbo/Cargo.toml | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1c4d05ba..0dd27954 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,4 +60,7 @@ ctor = "0.1.23" getset = "0.1.2" thiserror = "1.0.29" validator = "0.15" +bytes = "1.0.1" +tower-layer = "0.3.1" +tower-service = "0.3.1" diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml index 8874b4ce..6f74845c 100644 --- a/dubbo/Cargo.toml +++ b/dubbo/Cargo.toml @@ -19,9 +19,9 @@ futures-util = "0.3.23" futures-core = "0.3.23" tokio = { version = "1.0", features = ["rt-multi-thread", "time", "fs", "macros", "net", "signal"] } prost = "0.10.4" -async-trait = "0.1.56" -tower-layer = "0.3" -bytes = "1.0" +async-trait.worksapce = true +tower-layer.workspace = true +bytes.workspace = true pin-project.workspace = true rand = "0.8.5" serde_json.workspace = true From 80d06a4a0286050726c3a6b18be0031738c1e682 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 13:55:50 +0800 Subject: [PATCH 44/52] Ftr: config api --- config/src/lib.rs | 6 +++--- config/tests/test_api.rs | 8 ++++---- config/tests/test_use_root_dir.rs | 8 ++++---- dubbo/Cargo.toml | 2 +- dubbo/src/framework.rs | 4 ++-- dubbo/src/triple/transport/service.rs | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/config/src/lib.rs b/config/src/lib.rs index 8f79c2ac..04dec782 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -28,9 +28,9 @@ pub mod location; pub mod types; pub mod util; -pub(crate) static GLOBAL_ROOT_CONFIG: Lazy = +pub(crate) static DUBBO_CONFIG: Lazy = Lazy::new(|| ConfigWrapper::new(Arc::new(Mutex::new(RootConfig::default())))); -pub fn get_root_config() -> ConfigWrapper { - GLOBAL_ROOT_CONFIG.clone() +pub fn get_dubbo_config() -> ConfigWrapper { + DUBBO_CONFIG.clone() } diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 5d562688..8f48cb13 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -24,7 +24,7 @@ mod tests_api { use ctor::ctor; use config::api::ConfigApi; - use config::get_root_config; + use config::get_dubbo_config; use config::location::set_config_file_path; use config::types::protocol::Protocol; use config::types::registry::Registry; @@ -49,7 +49,7 @@ mod tests_api { #[test] fn test_dubbo_protocol_set_overwrite_yaml_by_api() -> Result<(), Error> { - let config_wrapper = get_root_config(); + let config_wrapper = get_dubbo_config(); let old_config = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(old_config.port, "8888".to_string()); config_wrapper.dubbo_protocol_set( @@ -73,14 +73,14 @@ mod tests_api { #[test] fn test_registry_config() -> Result<(), Error> { - let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK")?; + let zk_config: Registry = get_dubbo_config().dubbo_registry_get("demoZK")?; assert_eq!("zookeeper", zk_config.protocol); Ok(()) } #[test] fn test_default_value() -> Result<(), Error> { - let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK")?; + let zk_config: Registry = get_dubbo_config().dubbo_registry_get("demoZK")?; assert_eq!("3000", zk_config.timeout); Ok(()) } diff --git a/config/tests/test_use_root_dir.rs b/config/tests/test_use_root_dir.rs index 902dc102..ed39d039 100644 --- a/config/tests/test_use_root_dir.rs +++ b/config/tests/test_use_root_dir.rs @@ -20,13 +20,13 @@ mod tests_api { use anyhow::Error; use config::api::ConfigApi; - use config::get_root_config; + use config::get_dubbo_config; use config::types::protocol::Protocol; use config::types::registry::Registry; #[test] fn test_dubbo_protocol_set_overwrite_yaml_by_api() -> Result<(), Error> { - let config_wrapper = get_root_config(); + let config_wrapper = get_dubbo_config(); let old_config: Protocol = config_wrapper.dubbo_protocol_get("dubbo")?; assert_eq!(old_config.port, "8888"); println!("{}", old_config.ip); @@ -51,14 +51,14 @@ mod tests_api { #[test] fn test_registry_config() -> Result<(), Error> { - let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK")?; + let zk_config: Registry = get_dubbo_config().dubbo_registry_get("demoZK")?; assert_eq!("zookeeper", zk_config.protocol); Ok(()) } #[test] fn test_default_value() -> Result<(), Error> { - let zk_config: Registry = get_root_config().dubbo_registry_get("demoZK")?; + let zk_config: Registry = get_dubbo_config().dubbo_registry_get("demoZK")?; assert_eq!("3000", zk_config.timeout); Ok(()) } diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml index 6f74845c..85971b34 100644 --- a/dubbo/Cargo.toml +++ b/dubbo/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/apache/dubbo-rust.git" [dependencies] hyper = { version = "0.14.19", features = ["full"] } http = "0.2" -tower-service = "0.3.1" +tower-service.workspace = true http-body = "0.4.4" tower = { version = "0.4.12", features = ["timeout"] } futures-util = "0.3.23" diff --git a/dubbo/src/framework.rs b/dubbo/src/framework.rs index 8a697bcb..3e395bd1 100644 --- a/dubbo/src/framework.rs +++ b/dubbo/src/framework.rs @@ -34,7 +34,7 @@ use crate::{ BoxRegistry, Registry, }, }; -use dubbo_config::{get_root_config, protocol::ProtocolRetrieve, RootConfig}; +use dubbo_config::{get_dubbo_config, protocol::ProtocolRetrieve, RootConfig}; // Invoker是否可以基于hyper写一个通用的 @@ -74,7 +74,7 @@ impl Dubbo { pub fn init(&mut self) -> Result<(), Box> { if self.config.is_none() { - self.config = Some(get_root_config()) + self.config = Some(get_dubbo_config()) } let root_config = self.config.as_ref().unwrap(); diff --git a/dubbo/src/triple/transport/service.rs b/dubbo/src/triple/transport/service.rs index 0644823a..acc51f63 100644 --- a/dubbo/src/triple/transport/service.rs +++ b/dubbo/src/triple/transport/service.rs @@ -193,7 +193,7 @@ impl DubboServer { // impl BusinessConfig for DubboServer { // fn init() -> Self { -// let conf = config::get_root_config(); +// let conf = config::get_dubbo_config(); // DubboServer::new().with_accpet_http1(conf.bool("dubbo.server.accept_http2".to_string())) // } From 5350505ca1ffc6554bfda1ef4a875521a177ad49 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 16:00:22 +0800 Subject: [PATCH 45/52] Ftr: config api --- config/src/types/mod.rs | 10 +++++++++- config/src/types/protocol.rs | 10 ++++++++++ dubbo/src/framework.rs | 28 ++++++++++------------------ dubbo/src/triple/server/triple.rs | 11 ----------- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index 9c50cf0e..4a616d1c 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -15,13 +15,13 @@ * limitations under the License. */ -use crate::get_config_location; use crate::types::consumer::ConsumerConfig; use crate::types::protocol::ProtocolConfig; use crate::types::provider::ProviderConfig; use crate::types::registry::RegistryConfig; use crate::types::services::ServicesConfig; use crate::util::yaml_file_parser; +use crate::{get_config_location, get_dubbo_config}; use anyhow::Error; use base::constants::DUBBO_KEY; use getset::{CopyGetters, Getters, MutGetters, Setters}; @@ -76,6 +76,14 @@ impl Default for RootConfig { } } +impl ConfigWrapper { + pub fn leak_for_read(&self) -> &'static RootConfig { + let dubbo_config = get_dubbo_config(); + let guard = dubbo_config.inner.lock().unwrap(); + Box::leak(Box::new(guard.clone())) + } +} + #[derive(Clone)] pub struct ConfigWrapper { pub inner: Arc>, diff --git a/config/src/types/protocol.rs b/config/src/types/protocol.rs index f100935e..9ef84dfa 100644 --- a/config/src/types/protocol.rs +++ b/config/src/types/protocol.rs @@ -45,3 +45,13 @@ impl ConfigValidator for Protocol { todo!() } } + +impl Protocol { + pub fn to_url_string(&self, interface: &str) -> String { + let mut url = format!("{}://{}:{}/{}", self.name, self.ip, self.port, interface); + for (k, v) in self.params.iter() { + url = format!("{}&{}={}", url, k, v); + } + url + } +} diff --git a/dubbo/src/framework.rs b/dubbo/src/framework.rs index 3e395bd1..65c90db2 100644 --- a/dubbo/src/framework.rs +++ b/dubbo/src/framework.rs @@ -23,6 +23,7 @@ use std::{ }; use base::Url; +use config::{get_dubbo_config, RootConfig}; use futures::{future, Future}; use tracing::{debug, info}; @@ -34,7 +35,6 @@ use crate::{ BoxRegistry, Registry, }, }; -use dubbo_config::{get_dubbo_config, protocol::ProtocolRetrieve, RootConfig}; // Invoker是否可以基于hyper写一个通用的 @@ -42,7 +42,7 @@ use dubbo_config::{get_dubbo_config, protocol::ProtocolRetrieve, RootConfig}; pub struct Dubbo { protocols: HashMap>, registries: Option, - service_registry: HashMap>, // registry: Urls + service_registry: HashMap>, config: Option<&'static RootConfig>, } @@ -52,15 +52,10 @@ impl Dubbo { protocols: HashMap::new(), registries: None, service_registry: HashMap::new(), - config: None, + config: Some(get_dubbo_config().leak_for_read()), } } - pub fn with_config(mut self, config: RootConfig) -> Self { - self.config = Some(config.leak()); - self - } - pub fn add_registry(mut self, registry_key: &str, registry: BoxRegistry) -> Self { if self.registries.is_none() { self.registries = Some(Arc::new(Mutex::new(HashMap::new()))); @@ -73,24 +68,21 @@ impl Dubbo { } pub fn init(&mut self) -> Result<(), Box> { - if self.config.is_none() { - self.config = Some(get_dubbo_config()) - } - let root_config = self.config.as_ref().unwrap(); debug!("global conf: {:?}", root_config); - // env::set_var("ZOOKEEPER_SERVERS",root_config); for (_, service_config) in root_config.provider.services.iter() { info!("init service name: {}", service_config.interface); let url = if root_config .protocols .contains_key(service_config.protocol.as_str()) { - let protocol = root_config - .protocols - .get_protocol_or_default(service_config.protocol.as_str()); - let protocol_url = - format!("{}/{}", protocol.to_url(), service_config.interface.clone(),); + let protocol = root_config.protocols.get(service_config.protocol.as_str()); + if protocol.is_none() { + return Err(format!("protocol {:?} not exists", service_config.protocol).into()); + } + let protocol_url = protocol + .unwrap() + .to_url_string(service_config.interface.as_str()); info!("protocol_url: {:?}", protocol_url); Url::from_url(&protocol_url) } else { diff --git a/dubbo/src/triple/server/triple.rs b/dubbo/src/triple/server/triple.rs index 2c0626ce..cf08b842 100644 --- a/dubbo/src/triple/server/triple.rs +++ b/dubbo/src/triple/server/triple.rs @@ -29,7 +29,6 @@ use crate::{ }, BoxBody, }; -use dubbo_config::BusinessConfig; pub const GRPC_ACCEPT_ENCODING: &str = "grpc-accept-encoding"; pub const GRPC_ENCODING: &str = "grpc-encoding"; @@ -281,13 +280,3 @@ where Ok(compression) } } - -impl BusinessConfig for TripleServer { - fn init() -> Self { - todo!() - } - - fn load() -> Result<(), std::convert::Infallible> { - todo!() - } -} From b75cd708135f629004269b55939c548ceadb06de Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 16:06:01 +0800 Subject: [PATCH 46/52] Ftr: config api --- common/logger/src/tracing_configurer.rs | 7 ++----- config/src/lib.rs | 2 +- config/src/location.rs | 2 +- config/src/types/mod.rs | 7 ++++--- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/common/logger/src/tracing_configurer.rs b/common/logger/src/tracing_configurer.rs index 5beb77b2..9f24da19 100644 --- a/common/logger/src/tracing_configurer.rs +++ b/common/logger/src/tracing_configurer.rs @@ -18,15 +18,12 @@ // https://github.com/tokio-rs/tracing/issues/971 use crate::level::LevelWrapper; +use config::resolve_config_location; use config::util::yaml_key_reader; -use std::path::PathBuf; use tracing::debug; -use utils::path_util; pub(crate) fn default() { - let path_buf = PathBuf::new() - .join(path_util::app_root_dir()) - .join("../../../dubbo.yaml"); + let path_buf = resolve_config_location(); let level: LevelWrapper = yaml_key_reader(path_buf, "logging.level").unwrap().into(); tracing_subscriber::fmt() .compact() diff --git a/config/src/lib.rs b/config/src/lib.rs index 04dec782..872dceb6 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -20,7 +20,7 @@ use std::sync::{Arc, Mutex}; pub use crate::types::ConfigWrapper; pub use crate::types::RootConfig; -pub use location::get_config_location; +pub use location::resolve_config_location; pub mod api; pub mod error; diff --git a/config/src/location.rs b/config/src/location.rs index b4384ec5..7cde4bd4 100644 --- a/config/src/location.rs +++ b/config/src/location.rs @@ -21,7 +21,7 @@ use utils::env_util::get_env_value; use utils::path_util::app_root_dir; // resolve yaml config file -pub fn get_config_location() -> PathBuf { +pub fn resolve_config_location() -> PathBuf { let mut path_buf = PathBuf::new(); // resolve config path if get_env_value(ENV_DUBBO_CONFIG_PATH).is_some() { diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index 4a616d1c..d301290b 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -21,7 +21,7 @@ use crate::types::provider::ProviderConfig; use crate::types::registry::RegistryConfig; use crate::types::services::ServicesConfig; use crate::util::yaml_file_parser; -use crate::{get_config_location, get_dubbo_config}; +use crate::{get_dubbo_config, resolve_config_location}; use anyhow::Error; use base::constants::DUBBO_KEY; use getset::{CopyGetters, Getters, MutGetters, Setters}; @@ -69,9 +69,10 @@ pub struct RootConfig { impl Default for RootConfig { fn default() -> RootConfig { - let conf: HashMap = yaml_file_parser(get_config_location()).unwrap(); + let conf: HashMap = + yaml_file_parser(resolve_config_location()).unwrap(); let mut root_config: RootConfig = conf.get(DUBBO_KEY).unwrap().clone(); - root_config.location = get_config_location(); + root_config.location = resolve_config_location(); root_config } } From 29c7993d91aee19808b4864db93f5ffd4c134d7c Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 16:13:06 +0800 Subject: [PATCH 47/52] Ftr: config api --- common/base/src/url.rs | 6 +- common/logger/src/tracing_configurer.rs | 3 +- config/src/api.rs | 9 +- config/src/lib.rs | 3 +- config/src/location.rs | 3 +- config/src/types/consumer.rs | 6 +- config/src/types/default.rs | 6 +- config/src/types/mod.rs | 26 +-- config/src/types/services.rs | 3 +- config/src/util.rs | 9 +- config/tests/test_api.rs | 14 +- config/tests/test_use_root_dir.rs | 9 +- .../echo/src/generated/grpc.examples.echo.rs | 179 ++++++------------ examples/greeter/src/greeter/server.rs | 10 +- 14 files changed, 114 insertions(+), 172 deletions(-) diff --git a/common/base/src/url.rs b/common/base/src/url.rs index 0c52561f..ed500981 100644 --- a/common/base/src/url.rs +++ b/common/base/src/url.rs @@ -20,8 +20,10 @@ use std::{ fmt::{Display, Formatter}, }; -use crate::constants::{GROUP_KEY, INTERFACE_KEY, VERSION_KEY}; -use crate::types::alias::{ProtocolKey, ServiceKey, ServiceName}; +use crate::{ + constants::{GROUP_KEY, INTERFACE_KEY, VERSION_KEY}, + types::alias::{ProtocolKey, ServiceKey, ServiceName}, +}; use http::Uri; #[derive(Debug, Clone, Default, PartialEq)] diff --git a/common/logger/src/tracing_configurer.rs b/common/logger/src/tracing_configurer.rs index 9f24da19..79ad0ede 100644 --- a/common/logger/src/tracing_configurer.rs +++ b/common/logger/src/tracing_configurer.rs @@ -18,8 +18,7 @@ // https://github.com/tokio-rs/tracing/issues/971 use crate::level::LevelWrapper; -use config::resolve_config_location; -use config::util::yaml_key_reader; +use config::{resolve_config_location, util::yaml_key_reader}; use tracing::debug; pub(crate) fn default() { diff --git a/config/src/api.rs b/config/src/api.rs index 2a10c9c5..a632b06f 100644 --- a/config/src/api.rs +++ b/config/src/api.rs @@ -21,11 +21,10 @@ use crate::error::ConfigError; use anyhow::{anyhow, Error, Result}; use base::types::alias::ServiceName; -use crate::types::consumer::Reference; -use crate::types::protocol::Protocol; -use crate::types::registry::Registry; -use crate::types::services::Service; -use crate::ConfigWrapper; +use crate::{ + types::{consumer::Reference, protocol::Protocol, registry::Registry, services::Service}, + ConfigWrapper, +}; // could be used for config_center diff --git a/config/src/lib.rs b/config/src/lib.rs index 872dceb6..55a20caa 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -18,8 +18,7 @@ use once_cell::sync::Lazy; use std::sync::{Arc, Mutex}; -pub use crate::types::ConfigWrapper; -pub use crate::types::RootConfig; +pub use crate::types::{ConfigWrapper, RootConfig}; pub use location::resolve_config_location; pub mod api; diff --git a/config/src/location.rs b/config/src/location.rs index 7cde4bd4..eaa4a3dc 100644 --- a/config/src/location.rs +++ b/config/src/location.rs @@ -17,8 +17,7 @@ use base::constants::{DEFAULT_CONFIG_FILE, ENV_DUBBO_CONFIG_FILE, ENV_DUBBO_CONFIG_PATH}; use std::path::PathBuf; -use utils::env_util::get_env_value; -use utils::path_util::app_root_dir; +use utils::{env_util::get_env_value, path_util::app_root_dir}; // resolve yaml config file pub fn resolve_config_location() -> PathBuf { diff --git a/config/src/types/consumer.rs b/config/src/types/consumer.rs index 9ae0eac7..7cf405ea 100644 --- a/config/src/types/consumer.rs +++ b/config/src/types/consumer.rs @@ -18,11 +18,9 @@ use anyhow::Error; use std::collections::HashMap; -use serde::Deserialize; -use serde::Serialize; +use serde::{Deserialize, Serialize}; -use crate::types::default::*; -use crate::types::ConfigValidator; +use crate::types::{default::*, ConfigValidator}; use base::types::alias::{ ClusterStrategy, FilterKey, GroupId, InterfaceName, ParamKey, ProtocolKey, RegistryId, ServiceName, diff --git a/config/src/types/default.rs b/config/src/types/default.rs index b3614091..9151fc9e 100644 --- a/config/src/types/default.rs +++ b/config/src/types/default.rs @@ -15,8 +15,10 @@ * limitations under the License. */ -use base::constants::REGISTRY_TYPE_SERVICE; -use base::types::alias::{GroupId, RegistryType, VersionNumber}; +use base::{ + constants::REGISTRY_TYPE_SERVICE, + types::alias::{GroupId, RegistryType, VersionNumber}, +}; use utils::host_util; pub fn default_group_id() -> GroupId { diff --git a/config/src/types/mod.rs b/config/src/types/mod.rs index d301290b..afe36de0 100644 --- a/config/src/types/mod.rs +++ b/config/src/types/mod.rs @@ -15,21 +15,23 @@ * limitations under the License. */ -use crate::types::consumer::ConsumerConfig; -use crate::types::protocol::ProtocolConfig; -use crate::types::provider::ProviderConfig; -use crate::types::registry::RegistryConfig; -use crate::types::services::ServicesConfig; -use crate::util::yaml_file_parser; -use crate::{get_dubbo_config, resolve_config_location}; +use crate::{ + get_dubbo_config, resolve_config_location, + types::{ + consumer::ConsumerConfig, protocol::ProtocolConfig, provider::ProviderConfig, + registry::RegistryConfig, services::ServicesConfig, + }, + util::yaml_file_parser, +}; use anyhow::Error; use base::constants::DUBBO_KEY; use getset::{CopyGetters, Getters, MutGetters, Setters}; -use serde::Deserialize; -use serde::Serialize; -use std::collections::HashMap; -use std::path::PathBuf; -use std::sync::{Arc, Mutex}; +use serde::{Deserialize, Serialize}; +use std::{ + collections::HashMap, + path::PathBuf, + sync::{Arc, Mutex}, +}; pub mod consumer; pub mod default; diff --git a/config/src/types/services.rs b/config/src/types/services.rs index 96128636..7dcfa530 100644 --- a/config/src/types/services.rs +++ b/config/src/types/services.rs @@ -15,8 +15,7 @@ * limitations under the License. */ -use crate::types::default::*; -use crate::types::ConfigValidator; +use crate::types::{default::*, ConfigValidator}; use anyhow::Error; use base::types::alias::{ GroupId, InterfaceName, ProtocolId, SerializationKey, ServiceName, VersionNumber, diff --git a/config/src/util.rs b/config/src/util.rs index 11744761..e32af141 100644 --- a/config/src/util.rs +++ b/config/src/util.rs @@ -14,8 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use std::any::{Any, TypeId}; -use std::{collections::HashMap, fs, path::PathBuf, sync::Mutex}; +use std::{ + any::{Any, TypeId}, + collections::HashMap, + fs, + path::PathBuf, + sync::Mutex, +}; use anyhow::Error; use once_cell::sync::Lazy; diff --git a/config/tests/test_api.rs b/config/tests/test_api.rs index 8f48cb13..f55fda74 100644 --- a/config/tests/test_api.rs +++ b/config/tests/test_api.rs @@ -18,16 +18,16 @@ #[cfg(test)] mod tests_api { use anyhow::Error; - use std::env; - use std::sync::Once; + use std::{env, sync::Once}; use ctor::ctor; - use config::api::ConfigApi; - use config::get_dubbo_config; - use config::location::set_config_file_path; - use config::types::protocol::Protocol; - use config::types::registry::Registry; + use config::{ + api::ConfigApi, + get_dubbo_config, + location::set_config_file_path, + types::{protocol::Protocol, registry::Registry}, + }; static INIT: Once = Once::new(); diff --git a/config/tests/test_use_root_dir.rs b/config/tests/test_use_root_dir.rs index ed39d039..98cd8384 100644 --- a/config/tests/test_use_root_dir.rs +++ b/config/tests/test_use_root_dir.rs @@ -19,10 +19,11 @@ mod tests_api { use anyhow::Error; - use config::api::ConfigApi; - use config::get_dubbo_config; - use config::types::protocol::Protocol; - use config::types::registry::Registry; + use config::{ + api::ConfigApi, + get_dubbo_config, + types::{protocol::Protocol, registry::Registry}, + }; #[test] fn test_dubbo_protocol_set_overwrite_yaml_by_api() -> Result<(), Error> { diff --git a/examples/echo/src/generated/grpc.examples.echo.rs b/examples/echo/src/generated/grpc.examples.echo.rs index 8758f85a..ccb385cd 100644 --- a/examples/echo/src/generated/grpc.examples.echo.rs +++ b/examples/echo/src/generated/grpc.examples.echo.rs @@ -40,16 +40,12 @@ pub mod echo_client { &mut self, request: Request, ) -> Result, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("UnaryEcho")); - let path = http::uri::PathAndQuery::from_static( - "/grpc.examples.echo.Echo/UnaryEcho", - ); + let path = http::uri::PathAndQuery::from_static("/grpc.examples.echo.Echo/UnaryEcho"); self.inner.unary(request, codec, path, invocation).await } /// ServerStreamingEcho is server side streaming. @@ -57,51 +53,51 @@ pub mod echo_client { &mut self, request: Request, ) -> Result>, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ServerStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ServerStreamingEcho", ); - self.inner.server_streaming(request, codec, path, invocation).await + self.inner + .server_streaming(request, codec, path, invocation) + .await } /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ClientStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ClientStreamingEcho", ); - self.inner.client_streaming(request, codec, path, invocation).await + self.inner + .client_streaming(request, codec, path, invocation) + .await } /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result>, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("BidirectionalStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", ); - self.inner.bidi_streaming(request, codec, path, invocation).await + self.inner + .bidi_streaming(request, codec, path, invocation) + .await } } } @@ -118,9 +114,7 @@ pub mod echo_server { request: Request, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: futures_util::Stream< - Item = Result, - > + type ServerStreamingEchoStream: futures_util::Stream> + Send + 'static; /// ServerStreamingEcho is server side streaming. @@ -134,19 +128,14 @@ pub mod echo_server { request: Request>, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: futures_util::Stream< - Item = Result, - > + type BidirectionalStreamingEchoStream: futures_util::Stream> + Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, request: Request>, - ) -> Result< - Response, - dubbo::status::Status, - >; + ) -> Result, dubbo::status::Status>; } /// Echo is the echo service. #[derive(Debug)] @@ -176,10 +165,7 @@ pub mod echo_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready( - &mut self, - _cx: &mut Context<'_>, - ) -> Poll> { + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -192,26 +178,18 @@ pub mod echo_server { } impl UnarySvc for UnaryEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; - fn call( - &mut self, - request: Request, - ) -> Self::Future { + type Future = BoxFuture, dubbo::status::Status>; + fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.0.clone(); let fut = async move { inner.unary_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server.unary(UnaryEchoServer { inner }, req).await; Ok(res) }; @@ -222,32 +200,22 @@ pub mod echo_server { struct ServerStreamingEchoServer { inner: _Inner, } - impl ServerStreamingSvc - for ServerStreamingEchoServer { + impl ServerStreamingSvc for ServerStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; - fn call( - &mut self, - request: Request, - ) -> Self::Future { + type Future = + BoxFuture, dubbo::status::Status>; + fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.server_streaming_echo(request).await - }; + let fut = async move { inner.server_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server .server_streaming(ServerStreamingEchoServer { inner }, req) .await; @@ -260,31 +228,23 @@ pub mod echo_server { struct ClientStreamingEchoServer { inner: _Inner, } - impl ClientStreamingSvc - for ClientStreamingEchoServer { + impl ClientStreamingSvc for ClientStreamingEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; + type Future = BoxFuture, dubbo::status::Status>; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.client_streaming_echo(request).await - }; + let fut = async move { inner.client_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server .client_streaming(ClientStreamingEchoServer { inner }, req) .await; @@ -297,56 +257,41 @@ pub mod echo_server { struct BidirectionalStreamingEchoServer { inner: _Inner, } - impl StreamingSvc - for BidirectionalStreamingEchoServer { + impl StreamingSvc for BidirectionalStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; + type Future = + BoxFuture, dubbo::status::Status>; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.bidirectional_streaming_echo(request).await - }; + let fut = + async move { inner.bidirectional_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server - .bidi_streaming( - BidirectionalStreamingEchoServer { - inner, - }, - req, - ) + .bidi_streaming(BidirectionalStreamingEchoServer { inner }, req) .await; Ok(res) }; Box::pin(fut) } - _ => { - Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap(), - ) - }) - } + _ => Box::pin(async move { + Ok(http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap()) + }), } } } diff --git a/examples/greeter/src/greeter/server.rs b/examples/greeter/src/greeter/server.rs index 32931e5f..d82a7deb 100644 --- a/examples/greeter/src/greeter/server.rs +++ b/examples/greeter/src/greeter/server.rs @@ -23,7 +23,6 @@ use tokio::sync::mpsc; use tokio_stream::wrappers::ReceiverStream; use dubbo::{codegen::*, Dubbo}; -use dubbo_config::RootConfig; use logger::{ tracing::{info, span}, Level, @@ -51,14 +50,7 @@ async fn main() { name: "greeter".to_string(), }); let zkr = ZookeeperRegistry::default(); - let r = RootConfig::new(); - let r = match r.load() { - Ok(config) => config, - Err(_err) => panic!("err: {:?}", _err), // response was droped - }; - let mut f = Dubbo::new() - .with_config(r) - .add_registry("zookeeper", Box::new(zkr)); + let mut f = Dubbo::new().add_registry("zookeeper", Box::new(zkr)); f.start().await; } From 59ec9e81bfee02e78a9aa85e9d90d46f25cd984e Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 17:43:52 +0800 Subject: [PATCH 48/52] Ftr: config api --- Cargo.toml | 10 +- dubbo/Cargo.toml | 2 +- .../echo/src/generated/grpc.examples.echo.rs | 179 ++++++++++++------ 3 files changed, 121 insertions(+), 70 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0809b064..9a1f0501 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ protocol-dubbo2 = {path="./protocol/dubbo2"} protocol-triple = {path="./protocol/triple"} registry-zookeeper = {path="./registry/zookeeper"} registry-nacos = {path="./registry/nacos"} +config = {path="./config"} anyhow = "1.0.66" thiserror = "1.0.30" dubbo = { path = "./dubbo/" } @@ -57,13 +58,8 @@ serde_yaml = "0.9.4" # yaml file parser once_cell = "1.16.0" itertools = "0.10.1" bytes = "1.0" - - ctor = "0.1.23" getset = "0.1.2" -thiserror = "1.0.29" validator = "0.15" -bytes = "1.0.1" -tower-layer = "0.3.1" -tower-service = "0.3.1" - +tracing = "0.1.29" +tracing-subscriber = "0.3.1" diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml index 9047e640..54ef9257 100644 --- a/dubbo/Cargo.toml +++ b/dubbo/Cargo.toml @@ -36,6 +36,6 @@ urlencoding.workspace = true lazy_static.workspace = true base.workspace = true config.workspace = true - +logger.workspace = true #对象存储 state = { version = "0.5", features = ["tls"] } diff --git a/examples/echo/src/generated/grpc.examples.echo.rs b/examples/echo/src/generated/grpc.examples.echo.rs index ccb385cd..8758f85a 100644 --- a/examples/echo/src/generated/grpc.examples.echo.rs +++ b/examples/echo/src/generated/grpc.examples.echo.rs @@ -40,12 +40,16 @@ pub mod echo_client { &mut self, request: Request, ) -> Result, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("UnaryEcho")); - let path = http::uri::PathAndQuery::from_static("/grpc.examples.echo.Echo/UnaryEcho"); + let path = http::uri::PathAndQuery::from_static( + "/grpc.examples.echo.Echo/UnaryEcho", + ); self.inner.unary(request, codec, path, invocation).await } /// ServerStreamingEcho is server side streaming. @@ -53,51 +57,51 @@ pub mod echo_client { &mut self, request: Request, ) -> Result>, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ServerStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ServerStreamingEcho", ); - self.inner - .server_streaming(request, codec, path, invocation) - .await + self.inner.server_streaming(request, codec, path, invocation).await } /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ClientStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ClientStreamingEcho", ); - self.inner - .client_streaming(request, codec, path, invocation) - .await + self.inner.client_streaming(request, codec, path, invocation).await } /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result>, dubbo::status::Status> { - let codec = - dubbo::codegen::ProstCodec::::default(); + let codec = dubbo::codegen::ProstCodec::< + super::EchoRequest, + super::EchoResponse, + >::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("BidirectionalStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", ); - self.inner - .bidi_streaming(request, codec, path, invocation) - .await + self.inner.bidi_streaming(request, codec, path, invocation).await } } } @@ -114,7 +118,9 @@ pub mod echo_server { request: Request, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: futures_util::Stream> + type ServerStreamingEchoStream: futures_util::Stream< + Item = Result, + > + Send + 'static; /// ServerStreamingEcho is server side streaming. @@ -128,14 +134,19 @@ pub mod echo_server { request: Request>, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: futures_util::Stream> + type BidirectionalStreamingEchoStream: futures_util::Stream< + Item = Result, + > + Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, request: Request>, - ) -> Result, dubbo::status::Status>; + ) -> Result< + Response, + dubbo::status::Status, + >; } /// Echo is the echo service. #[derive(Debug)] @@ -165,7 +176,10 @@ pub mod echo_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -178,18 +192,26 @@ pub mod echo_server { } impl UnarySvc for UnaryEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture, dubbo::status::Status>; - fn call(&mut self, request: Request) -> Self::Future { + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; + fn call( + &mut self, + request: Request, + ) -> Self::Future { let inner = self.inner.0.clone(); let fut = async move { inner.unary_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server.unary(UnaryEchoServer { inner }, req).await; Ok(res) }; @@ -200,22 +222,32 @@ pub mod echo_server { struct ServerStreamingEchoServer { inner: _Inner, } - impl ServerStreamingSvc for ServerStreamingEchoServer { + impl ServerStreamingSvc + for ServerStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; - type Future = - BoxFuture, dubbo::status::Status>; - fn call(&mut self, request: Request) -> Self::Future { + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; + fn call( + &mut self, + request: Request, + ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { inner.server_streaming_echo(request).await }; + let fut = async move { + inner.server_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server .server_streaming(ServerStreamingEchoServer { inner }, req) .await; @@ -228,23 +260,31 @@ pub mod echo_server { struct ClientStreamingEchoServer { inner: _Inner, } - impl ClientStreamingSvc for ClientStreamingEchoServer { + impl ClientStreamingSvc + for ClientStreamingEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture, dubbo::status::Status>; + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { inner.client_streaming_echo(request).await }; + let fut = async move { + inner.client_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server .client_streaming(ClientStreamingEchoServer { inner }, req) .await; @@ -257,41 +297,56 @@ pub mod echo_server { struct BidirectionalStreamingEchoServer { inner: _Inner, } - impl StreamingSvc for BidirectionalStreamingEchoServer { + impl StreamingSvc + for BidirectionalStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; - type Future = - BoxFuture, dubbo::status::Status>; + type Future = BoxFuture< + Response, + dubbo::status::Status, + >; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = - async move { inner.bidirectional_streaming_echo(request).await }; + let fut = async move { + inner.bidirectional_streaming_echo(request).await + }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default()); + let mut server = TripleServer::new( + dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default(), + ); let res = server - .bidi_streaming(BidirectionalStreamingEchoServer { inner }, req) + .bidi_streaming( + BidirectionalStreamingEchoServer { + inner, + }, + req, + ) .await; Ok(res) }; Box::pin(fut) } - _ => Box::pin(async move { - Ok(http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap()) - }), + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } } } } From f01336a47073c8f860629b8ebdae8870a7dc98d5 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 18:27:01 +0800 Subject: [PATCH 49/52] Ftr: config api --- .../echo/src/generated/grpc.examples.echo.rs | 179 ++++++------------ 1 file changed, 62 insertions(+), 117 deletions(-) diff --git a/examples/echo/src/generated/grpc.examples.echo.rs b/examples/echo/src/generated/grpc.examples.echo.rs index 8758f85a..ccb385cd 100644 --- a/examples/echo/src/generated/grpc.examples.echo.rs +++ b/examples/echo/src/generated/grpc.examples.echo.rs @@ -40,16 +40,12 @@ pub mod echo_client { &mut self, request: Request, ) -> Result, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("UnaryEcho")); - let path = http::uri::PathAndQuery::from_static( - "/grpc.examples.echo.Echo/UnaryEcho", - ); + let path = http::uri::PathAndQuery::from_static("/grpc.examples.echo.Echo/UnaryEcho"); self.inner.unary(request, codec, path, invocation).await } /// ServerStreamingEcho is server side streaming. @@ -57,51 +53,51 @@ pub mod echo_client { &mut self, request: Request, ) -> Result>, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ServerStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ServerStreamingEcho", ); - self.inner.server_streaming(request, codec, path, invocation).await + self.inner + .server_streaming(request, codec, path, invocation) + .await } /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("ClientStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/ClientStreamingEcho", ); - self.inner.client_streaming(request, codec, path, invocation).await + self.inner + .client_streaming(request, codec, path, invocation) + .await } /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, request: impl IntoStreamingRequest, ) -> Result>, dubbo::status::Status> { - let codec = dubbo::codegen::ProstCodec::< - super::EchoRequest, - super::EchoResponse, - >::default(); + let codec = + dubbo::codegen::ProstCodec::::default(); let invocation = RpcInvocation::default() .with_service_unique_name(String::from("grpc.examples.echo.Echo")) .with_method_name(String::from("BidirectionalStreamingEcho")); let path = http::uri::PathAndQuery::from_static( "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", ); - self.inner.bidi_streaming(request, codec, path, invocation).await + self.inner + .bidi_streaming(request, codec, path, invocation) + .await } } } @@ -118,9 +114,7 @@ pub mod echo_server { request: Request, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: futures_util::Stream< - Item = Result, - > + type ServerStreamingEchoStream: futures_util::Stream> + Send + 'static; /// ServerStreamingEcho is server side streaming. @@ -134,19 +128,14 @@ pub mod echo_server { request: Request>, ) -> Result, dubbo::status::Status>; ///Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: futures_util::Stream< - Item = Result, - > + type BidirectionalStreamingEchoStream: futures_util::Stream> + Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, request: Request>, - ) -> Result< - Response, - dubbo::status::Status, - >; + ) -> Result, dubbo::status::Status>; } /// Echo is the echo service. #[derive(Debug)] @@ -176,10 +165,7 @@ pub mod echo_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready( - &mut self, - _cx: &mut Context<'_>, - ) -> Poll> { + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -192,26 +178,18 @@ pub mod echo_server { } impl UnarySvc for UnaryEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; - fn call( - &mut self, - request: Request, - ) -> Self::Future { + type Future = BoxFuture, dubbo::status::Status>; + fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.0.clone(); let fut = async move { inner.unary_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server.unary(UnaryEchoServer { inner }, req).await; Ok(res) }; @@ -222,32 +200,22 @@ pub mod echo_server { struct ServerStreamingEchoServer { inner: _Inner, } - impl ServerStreamingSvc - for ServerStreamingEchoServer { + impl ServerStreamingSvc for ServerStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; - fn call( - &mut self, - request: Request, - ) -> Self::Future { + type Future = + BoxFuture, dubbo::status::Status>; + fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.server_streaming_echo(request).await - }; + let fut = async move { inner.server_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server .server_streaming(ServerStreamingEchoServer { inner }, req) .await; @@ -260,31 +228,23 @@ pub mod echo_server { struct ClientStreamingEchoServer { inner: _Inner, } - impl ClientStreamingSvc - for ClientStreamingEchoServer { + impl ClientStreamingSvc for ClientStreamingEchoServer { type Response = super::EchoResponse; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; + type Future = BoxFuture, dubbo::status::Status>; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.client_streaming_echo(request).await - }; + let fut = async move { inner.client_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server .client_streaming(ClientStreamingEchoServer { inner }, req) .await; @@ -297,56 +257,41 @@ pub mod echo_server { struct BidirectionalStreamingEchoServer { inner: _Inner, } - impl StreamingSvc - for BidirectionalStreamingEchoServer { + impl StreamingSvc for BidirectionalStreamingEchoServer { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; - type Future = BoxFuture< - Response, - dubbo::status::Status, - >; + type Future = + BoxFuture, dubbo::status::Status>; fn call( &mut self, request: Request>, ) -> Self::Future { let inner = self.inner.0.clone(); - let fut = async move { - inner.bidirectional_streaming_echo(request).await - }; + let fut = + async move { inner.bidirectional_streaming_echo(request).await }; Box::pin(fut) } } let fut = async move { - let mut server = TripleServer::new( - dubbo::codegen::ProstCodec::< - super::EchoResponse, - super::EchoRequest, - >::default(), - ); + let mut server = TripleServer::new(dubbo::codegen::ProstCodec::< + super::EchoResponse, + super::EchoRequest, + >::default()); let res = server - .bidi_streaming( - BidirectionalStreamingEchoServer { - inner, - }, - req, - ) + .bidi_streaming(BidirectionalStreamingEchoServer { inner }, req) .await; Ok(res) }; Box::pin(fut) } - _ => { - Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap(), - ) - }) - } + _ => Box::pin(async move { + Ok(http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap()) + }), } } } From fb96b3f4c8423ed265991f4cc5329e7f8ab659e9 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 19:16:11 +0800 Subject: [PATCH 50/52] Ftr: config api --- common/utils/src/env_util.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/common/utils/src/env_util.rs b/common/utils/src/env_util.rs index d6c8678a..41348740 100644 --- a/common/utils/src/env_util.rs +++ b/common/utils/src/env_util.rs @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ use std::env; pub fn get_env_value(env_key: &str) -> Option { From 52f9fdef7e6619730d03bd8fa30dbb5cac38ad24 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 19:55:59 +0800 Subject: [PATCH 51/52] Ftr: config api --- dubbo/src/framework.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo/src/framework.rs b/dubbo/src/framework.rs index 65c90db2..8985ae5d 100644 --- a/dubbo/src/framework.rs +++ b/dubbo/src/framework.rs @@ -25,7 +25,7 @@ use std::{ use base::Url; use config::{get_dubbo_config, RootConfig}; use futures::{future, Future}; -use tracing::{debug, info}; +use logger::tracing::{debug, info}; use crate::{ protocol::{BoxExporter, Protocol}, From 9af298b7f51823ced6325a42c413478574265881 Mon Sep 17 00:00:00 2001 From: liuyuancheng Date: Tue, 7 Mar 2023 20:19:51 +0800 Subject: [PATCH 52/52] Ftr: config api --- .github/workflows/github-actions.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index e8881e01..1db92165 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -94,5 +94,4 @@ jobs: ../../target/debug/greeter-client env: ZOOKEEPER_SERVERS: 127.0.0.1:2181 - DUBBO_CONFIG_PATH: ./dubbo.yaml working-directory: examples/greeter