-
Notifications
You must be signed in to change notification settings - Fork 181
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Motivation: Allow users to intercept static factories that create client/server builders to enhance builders' behavior. Users can use these providers to override default values on the builders or to intercept builders for metrics purposes. Modifications: - Add `HttpProviders` and `GrpcProviders` that define provider interfaces for `ServiceLoader`; - Test how users can intercept builders; Result: Users can change the default builders using providers that are automatically loaded via `ServiceLoader`.
- Loading branch information
1 parent
0124d9f
commit 13107f8
Showing
26 changed files
with
1,798 additions
and
43 deletions.
There are no files selected for viewing
77 changes: 77 additions & 0 deletions
77
servicetalk-grpc-api/src/main/java/io/servicetalk/grpc/api/DelegatingGrpcClientBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright © 2022 Apple Inc. and the ServiceTalk project authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.servicetalk.grpc.api; | ||
|
||
import java.time.Duration; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* A {@link GrpcClientBuilder} that delegates all methods to another {@link GrpcClientBuilder}. | ||
* | ||
* @param <U> the type of address before resolution (unresolved address) | ||
* @param <R> the type of address after resolution (resolved address) | ||
*/ | ||
public class DelegatingGrpcClientBuilder<U, R> implements GrpcClientBuilder<U, R> { | ||
|
||
private GrpcClientBuilder<U, R> delegate; | ||
|
||
public DelegatingGrpcClientBuilder(final GrpcClientBuilder<U, R> delegate) { | ||
this.delegate = requireNonNull(delegate); | ||
} | ||
|
||
/** | ||
* Returns the {@link GrpcClientBuilder} delegate. | ||
* | ||
* @return Delegate {@link GrpcClientBuilder}. | ||
*/ | ||
protected final GrpcClientBuilder<U, R> delegate() { | ||
return delegate; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return this.getClass().getSimpleName() + "{delegate=" + delegate() + '}'; | ||
} | ||
|
||
@Override | ||
public GrpcClientBuilder<U, R> initializeHttp(final HttpInitializer<U, R> initializer) { | ||
delegate = delegate.initializeHttp(initializer); | ||
return this; | ||
} | ||
|
||
@Override | ||
public GrpcClientBuilder<U, R> defaultTimeout(final Duration defaultTimeout) { | ||
delegate = delegate.defaultTimeout(defaultTimeout); | ||
return this; | ||
} | ||
|
||
@Override | ||
public <Client extends GrpcClient<?>> Client build(final GrpcClientFactory<Client, ?> clientFactory) { | ||
return delegate.build(clientFactory); | ||
} | ||
|
||
@Override | ||
public <BlockingClient extends BlockingGrpcClient<?>> BlockingClient buildBlocking( | ||
final GrpcClientFactory<?, BlockingClient> clientFactory) { | ||
return delegate.buildBlocking(clientFactory); | ||
} | ||
|
||
@Override | ||
public MultiClientBuilder buildMulti() { | ||
return delegate.buildMulti(); | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
servicetalk-grpc-api/src/main/java/io/servicetalk/grpc/api/DelegatingGrpcServerBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* Copyright © 2022 Apple Inc. and the ServiceTalk project authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.servicetalk.grpc.api; | ||
|
||
import io.servicetalk.concurrent.api.Single; | ||
|
||
import java.time.Duration; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* A {@link GrpcServerBuilder} that delegates all methods to another {@link GrpcServerBuilder}. | ||
*/ | ||
public class DelegatingGrpcServerBuilder implements GrpcServerBuilder { | ||
|
||
private GrpcServerBuilder delegate; | ||
|
||
public DelegatingGrpcServerBuilder(final GrpcServerBuilder delegate) { | ||
this.delegate = requireNonNull(delegate); | ||
} | ||
|
||
/** | ||
* Returns the {@link GrpcServerBuilder} delegate. | ||
* | ||
* @return Delegate {@link GrpcServerBuilder}. | ||
*/ | ||
protected final GrpcServerBuilder delegate() { | ||
return delegate; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return this.getClass().getSimpleName() + "{delegate=" + delegate() + '}'; | ||
} | ||
|
||
@Override | ||
public GrpcServerBuilder initializeHttp(final HttpInitializer initializer) { | ||
delegate = delegate.initializeHttp(initializer); | ||
return this; | ||
} | ||
|
||
@Override | ||
public GrpcServerBuilder defaultTimeout(final Duration defaultTimeout) { | ||
delegate = delegate.defaultTimeout(defaultTimeout); | ||
return this; | ||
} | ||
|
||
@Override | ||
public GrpcServerBuilder lifecycleObserver(final GrpcLifecycleObserver lifecycleObserver) { | ||
delegate = delegate.lifecycleObserver(lifecycleObserver); | ||
return this; | ||
} | ||
|
||
@Override | ||
public Single<GrpcServerContext> listen(final GrpcBindableService<?>... services) { | ||
return delegate.listen(services); | ||
} | ||
|
||
@Override | ||
public Single<GrpcServerContext> listen(final GrpcServiceFactory<?>... serviceFactories) { | ||
return delegate.listen(serviceFactories); | ||
} | ||
|
||
@Override | ||
public GrpcServerContext listenAndAwait(final GrpcServiceFactory<?>... serviceFactories) throws Exception { | ||
return delegate.listenAndAwait(serviceFactories); | ||
} | ||
|
||
@Override | ||
public GrpcServerContext listenAndAwait(final GrpcBindableService<?>... services) throws Exception { | ||
return delegate.listenAndAwait(services); | ||
} | ||
} |
82 changes: 82 additions & 0 deletions
82
servicetalk-grpc-api/src/main/java/io/servicetalk/grpc/api/GrpcProviders.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright © 2022 Apple Inc. and the ServiceTalk project authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.servicetalk.grpc.api; | ||
|
||
import io.servicetalk.http.api.HttpProviders; | ||
import io.servicetalk.http.api.HttpProviders.HttpServerBuilderProvider; | ||
import io.servicetalk.http.api.HttpProviders.SingleAddressHttpClientBuilderProvider; | ||
|
||
import java.net.SocketAddress; | ||
import java.util.ServiceLoader; | ||
|
||
/** | ||
* A holder for all gRPC-specific providers that can be registered using {@link ServiceLoader}. | ||
* | ||
* @see HttpProviders | ||
*/ | ||
public final class GrpcProviders { | ||
|
||
private GrpcProviders() { | ||
// No instances. | ||
} | ||
|
||
/** | ||
* Provider for {@link GrpcClientBuilder}. | ||
* <p> | ||
* An HTTP layer should use {@link SingleAddressHttpClientBuilderProvider}. | ||
*/ | ||
@FunctionalInterface | ||
public interface GrpcClientBuilderProvider { | ||
|
||
/** | ||
* Returns a {@link GrpcClientBuilder} based on the address and pre-initialized {@link GrpcClientBuilder}. | ||
* <p> | ||
* This method may return the pre-initialized {@code builder} as-is, or apply custom builder settings before | ||
* returning it, or wrap it ({@link DelegatingGrpcClientBuilder} may be helpful). | ||
* | ||
* @param address a remote address used to create a {@link GrpcClientBuilder}, it can be resolved or unresolved | ||
* based on the factory used | ||
* @param builder pre-initialized {@link GrpcClientBuilder} | ||
* @param <U> the type of address before resolution (unresolved address) | ||
* @param <R> the type of address after resolution (resolved address) | ||
* @return a {@link GrpcClientBuilder} based on the address and pre-initialized {@link GrpcClientBuilder}. | ||
* @see DelegatingGrpcClientBuilder | ||
*/ | ||
<U, R> GrpcClientBuilder<U, R> newBuilder(U address, GrpcClientBuilder<U, R> builder); | ||
} | ||
|
||
/** | ||
* Provider for {@link GrpcServerBuilder}. | ||
* <p> | ||
* An HTTP layer should use {@link HttpServerBuilderProvider}. | ||
*/ | ||
@FunctionalInterface | ||
public interface GrpcServerBuilderProvider { | ||
|
||
/** | ||
* Returns a {@link GrpcServerBuilder} based on the address and pre-initialized {@link GrpcServerBuilder}. | ||
* <p> | ||
* This method may return the pre-initialized {@code builder} as-is, or apply custom builder settings before | ||
* returning it, or wrap it ({@link DelegatingGrpcServerBuilder} may be helpful). | ||
* | ||
* @param address a server address used to create a {@link GrpcServerBuilder} | ||
* @param builder pre-initialized {@link GrpcServerBuilder} | ||
* @return a {@link GrpcServerBuilder} based on the address and pre-initialized{@link GrpcServerBuilder}. | ||
* @see DelegatingGrpcServerBuilder | ||
*/ | ||
GrpcServerBuilder newBuilder(SocketAddress address, GrpcServerBuilder builder); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.