io.grpc.netty.NettyChannelBuilder Java Examples
The following examples show how to use
io.grpc.netty.NettyChannelBuilder.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: GoogleAuthUtils.java From bazel with Apache License 2.0 | 6 votes |
private static NettyChannelBuilder newNettyChannelBuilder(String targetUrl, String proxy) throws IOException { if (Strings.isNullOrEmpty(proxy)) { return NettyChannelBuilder.forTarget(targetUrl).defaultLoadBalancingPolicy("round_robin"); } if (!proxy.startsWith("unix:")) { throw new IOException("Remote proxy unsupported: " + proxy); } DomainSocketAddress address = new DomainSocketAddress(proxy.replaceFirst("^unix:", "")); NettyChannelBuilder builder = NettyChannelBuilder.forAddress(address).overrideAuthority(targetUrl); if (KQueue.isAvailable()) { return builder .channelType(KQueueDomainSocketChannel.class) .eventLoopGroup(new KQueueEventLoopGroup()); } if (Epoll.isAvailable()) { return builder .channelType(EpollDomainSocketChannel.class) .eventLoopGroup(new EpollEventLoopGroup()); } throw new IOException("Unix domain sockets are unsupported on this platform"); }
Example #2
Source File: GrpcChannelBuilderFactory.java From micronaut-grpc with Apache License 2.0 | 6 votes |
/** * Constructor a managed channel build for the given target name and interceptors. * @param target The target name * @param interceptors The interceptors * @return The channel builder */ @Bean @Prototype protected NettyChannelBuilder managedChannelBuilder(@Parameter String target, List<ClientInterceptor> interceptors) { GrpcManagedChannelConfiguration config = beanContext.findBean(GrpcManagedChannelConfiguration.class, Qualifiers.byName(target)).orElseGet(() -> { final GrpcDefaultManagedChannelConfiguration mcc = new GrpcDefaultManagedChannelConfiguration( target, beanContext.getEnvironment(), executorService ); beanContext.inject(mcc); return mcc; } ); final NettyChannelBuilder channelBuilder = config.getChannelBuilder(); if (CollectionUtils.isNotEmpty(interceptors)) { channelBuilder.intercept(interceptors); } return channelBuilder; }
Example #3
Source File: DefaultChannelFactory.java From pinpoint with Apache License 2.0 | 6 votes |
private void setupClientOption(final NettyChannelBuilder channelBuilder) { channelBuilder.keepAliveTime(clientOption.getKeepAliveTime(), TimeUnit.MILLISECONDS); channelBuilder.keepAliveTimeout(clientOption.getKeepAliveTimeout(), TimeUnit.MILLISECONDS); channelBuilder.keepAliveWithoutCalls(clientOption.isKeepAliveWithoutCalls()); channelBuilder.maxHeaderListSize(clientOption.getMaxHeaderListSize()); channelBuilder.maxInboundMessageSize(clientOption.getMaxInboundMessageSize()); channelBuilder.flowControlWindow(clientOption.getFlowControlWindow()); channelBuilder.idleTimeout(clientOption.getIdleTimeoutMillis(), TimeUnit.MILLISECONDS); // ChannelOption channelBuilder.withOption(ChannelOption.TCP_NODELAY, true); channelBuilder.withOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, clientOption.getConnectTimeout()); final WriteBufferWaterMark writeBufferWaterMark = new WriteBufferWaterMark(clientOption.getWriteBufferLowWaterMark(), clientOption.getWriteBufferHighWaterMark()); channelBuilder.withOption(ChannelOption.WRITE_BUFFER_WATER_MARK, writeBufferWaterMark); if (logger.isInfoEnabled()) { logger.info("Set clientOption {}. name={}", clientOption, factoryName); } }
Example #4
Source File: Client.java From startup-os with Apache License 2.0 | 6 votes |
public static void main(String[] args) throws Exception { Flags.parseCurrentPackage(args); SslContext sslContext = GrpcSslContexts.forClient().trustManager(new File(certificateFile.get())).build(); ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", GRPC_PORT).sslContext(sslContext).build(); GrpcAuthTestGrpc.GrpcAuthTestBlockingStub stub = GrpcAuthTestGrpc.newBlockingStub(channel) .withInterceptors(new ClientAuthInterceptor(token.get())); logger.at(Level.INFO).log("Calling server to increment %d", n.get()); Protos.Response resp = stub.getNextNumber(Protos.Request.newBuilder().setNumber(n.get()).build()); logger.at(Level.INFO).log("Got %d in response", resp.getNumber()); }
Example #5
Source File: DefaultChannelFactory.java From pinpoint with Apache License 2.0 | 6 votes |
@Override public ManagedChannel build(String channelName, String host, int port) { final NettyChannelBuilder channelBuilder = NettyChannelBuilder.forAddress(host, port); channelBuilder.usePlaintext(); channelBuilder.eventLoopGroup(eventLoopGroup); setupInternal(channelBuilder); addHeader(channelBuilder); addClientInterceptor(channelBuilder); channelBuilder.executor(executorService); if (this.nameResolverProvider != null) { logger.info("Set nameResolverProvider {}. channelName={}, host={}, port={}", this.nameResolverProvider, channelName, host, port); channelBuilder.nameResolverFactory(this.nameResolverProvider); } setupClientOption(channelBuilder); final ManagedChannel channel = channelBuilder.build(); return channel; }
Example #6
Source File: GrpcChannelBuilderFactory.java From micronaut-grpc with Apache License 2.0 | 6 votes |
/** * Constructor a managed channel build for the given target name and interceptors. * @param target The target name * @param interceptors The interceptors * @return The channel builder */ @Bean @Prototype protected NettyChannelBuilder managedChannelBuilder(@Parameter String target, List<ClientInterceptor> interceptors) { GrpcManagedChannelConfiguration config = beanContext.findBean(GrpcManagedChannelConfiguration.class, Qualifiers.byName(target)).orElseGet(() -> { final GrpcDefaultManagedChannelConfiguration mcc = new GrpcDefaultManagedChannelConfiguration( target, beanContext.getEnvironment(), executorService ); beanContext.inject(mcc); return mcc; } ); final NettyChannelBuilder channelBuilder = config.getChannelBuilder(); if (CollectionUtils.isNotEmpty(interceptors)) { channelBuilder.intercept(interceptors); } return channelBuilder; }
Example #7
Source File: RemoteSignatureSource.java From compass with GNU Affero General Public License v3.0 | 6 votes |
private ManagedChannelBuilder createSecureManagedChannelBuilder(String uri, String trustCertCollectionFilePath, String clientCertChainFilePath, String clientPrivateKeyFilePath) throws SSLException { String cacheTtl = Security.getProperty("networkaddress.cache.ttl"); if (cacheTtl == null) { cacheTtl = DEFAULT_CACHE_TTL; } return NettyChannelBuilder .forTarget(uri) .idleTimeout(Integer.valueOf(cacheTtl) * 2, TimeUnit.SECONDS) .useTransportSecurity() .sslContext( buildSslContext(trustCertCollectionFilePath, clientCertChainFilePath, clientPrivateKeyFilePath) ); }
Example #8
Source File: BaseIT.java From kafka-pubsub-emulator with Apache License 2.0 | 6 votes |
public static AdminGrpc.AdminBlockingStub getAdminStub() { ManagedChannel channel = null; if (USE_SSL) { File certificate = new File(configurationRepository.getServer().getSecurity().getCertificateChainFile()); try { channel = NettyChannelBuilder.forAddress(LOCALHOST, PORT) .maxInboundMessageSize(100000) .sslContext(GrpcSslContexts.forClient().trustManager(certificate).build()) .build(); } catch (SSLException e) { fail("Unable to create SSL channel " + e.getMessage()); } } else { channel = ManagedChannelBuilder.forAddress(LOCALHOST, PORT).usePlaintext(true).build(); } return AdminGrpc.newBlockingStub(channel); }
Example #9
Source File: KMSEncryptionProvider.java From credhub with Apache License 2.0 | 6 votes |
public KMSEncryptionProvider(final EncryptionConfiguration configuration) { super(); setChannelInfo(); SslContext sslContext; try { sslContext = GrpcSslContexts.forClient() .trustManager(new ByteArrayInputStream(configuration.getCa().getBytes(UTF_8))) .build(); } catch (SSLException e) { throw new RuntimeException(e); } blockingStub = KeyManagementServiceGrpc.newBlockingStub( NettyChannelBuilder.forAddress(new DomainSocketAddress(configuration.getEndpoint())) .eventLoopGroup(group) .channelType(channelType) .keepAliveTime(DEFAULT_KEEPALIVE_TIMEOUT_NANOS, TimeUnit.NANOSECONDS) .useTransportSecurity() .sslContext(sslContext) .overrideAuthority(configuration.getHost()) .build()); }
Example #10
Source File: ConcurrencyTest.java From grpc-java with Apache License 2.0 | 6 votes |
private ManagedChannel newClientChannel() throws CertificateException, IOException { File clientCertChainFile = TestUtils.loadCert("client.pem"); File clientPrivateKeyFile = TestUtils.loadCert("client.key"); X509Certificate[] clientTrustedCaCerts = { TestUtils.loadX509Cert("ca.pem") }; SslContext sslContext = GrpcSslContexts.forClient() .keyManager(clientCertChainFile, clientPrivateKeyFile) .trustManager(clientTrustedCaCerts) .build(); return NettyChannelBuilder.forAddress("localhost", server.getPort()) .overrideAuthority(TestUtils.TEST_SERVER_HOST) .negotiationType(NegotiationType.TLS) .sslContext(sslContext) .build(); }
Example #11
Source File: SmartContractBase.java From julongchain with Apache License 2.0 | 6 votes |
public ManagedChannel newPeerClientConnection() { final NettyChannelBuilder builder = NettyChannelBuilder.forAddress(host, port).maxInboundMessageSize(CommConstant.MAX_GRPC_MESSAGE_SIZE); logger.info("Configuring channel connection to peer."); if (tlsEnabled) { logger.info("TLS is enabled"); try { final SslContext sslContext = GrpcSslContexts.forClient().trustManager(new File(this.rootCertFile)).build(); builder.negotiationType(NegotiationType.TLS); if (!hostOverrideAuthority.equals("")) { logger.info("Host override " + hostOverrideAuthority); builder.overrideAuthority(hostOverrideAuthority); } builder.sslContext(sslContext); logger.info("TLS context built: " + sslContext); } catch (SSLException e) { logger.error("failed connect to peer with SSLException", e); } } else { builder.usePlaintext(); } return builder.build(); }
Example #12
Source File: ConcurrencyTest.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
private ManagedChannel newClientChannel() throws CertificateException, IOException { File clientCertChainFile = TestUtils.loadCert("client.pem"); File clientPrivateKeyFile = TestUtils.loadCert("client.key"); X509Certificate[] clientTrustedCaCerts = { TestUtils.loadX509Cert("ca.pem") }; SslContext sslContext = GrpcSslContexts.forClient() .keyManager(clientCertChainFile, clientPrivateKeyFile) .trustManager(clientTrustedCaCerts) .build(); return NettyChannelBuilder.forAddress("localhost", server.getPort()) .overrideAuthority(TestUtils.TEST_SERVER_HOST) .negotiationType(NegotiationType.TLS) .sslContext(sslContext) .build(); }
Example #13
Source File: GrpcServerTestBase.java From grpc-spring-boot-starter with Apache License 2.0 | 6 votes |
@Before public final void setupChannels() throws IOException { if(gRpcServerProperties.isEnabled()) { ManagedChannelBuilder<?> channelBuilder = ManagedChannelBuilder.forAddress("localhost", getPort()); Resource certChain = Optional.ofNullable(gRpcServerProperties.getSecurity()) .map(GRpcServerProperties.SecurityProperties::getCertChain) .orElse(null); if(null!= certChain){ ((NettyChannelBuilder)channelBuilder) .useTransportSecurity() .sslContext(GrpcSslContexts.forClient().trustManager(certChain.getInputStream()).build()); }else{ channelBuilder.usePlaintext(); } channel = onChannelBuild(channelBuilder).build(); } if(StringUtils.hasText(gRpcServerProperties.getInProcessServerName())){ inProcChannel = onChannelBuild( InProcessChannelBuilder.forName(gRpcServerProperties.getInProcessServerName()) .usePlaintext() ).build(); } }
Example #14
Source File: NodeServer.java From julongchain with Apache License 2.0 | 6 votes |
private void startGossipService() { String consenterAddress = NodeConfigFactory.getNodeConfig().getNode().getGossip().getConsenterAddress(); String[] split = StringUtils.split(consenterAddress, ":"); String host = split[0]; Integer port = Integer.parseInt(split[1]); waitConnectable(host, port); ManagedChannel managedChannel = NettyChannelBuilder.forAddress(host, port).maxInboundMessageSize(CommConstant.MAX_GRPC_MESSAGE_SIZE) .usePlaintext().build(); GossipClientStream gossipClientStream = new GossipClientStream(managedChannel); GossipClientStream.setGossipClientStream(gossipClientStream); try { List<String> ledgerIDs = LedgerManager.getLedgerIDs(); for (String ledgerID : ledgerIDs) { startPullFromConsenter(gossipClientStream, ledgerID); } } catch (LedgerException e) { log.error(e.getMessage(), e); } }
Example #15
Source File: SmartContractShimTest.java From julongchain with Apache License 2.0 | 6 votes |
@Before public void init() { NettyChannelBuilder nettyChannelBuilder = NettyChannelBuilder.forAddress(host, port).usePlaintext(); ManagedChannel managedChannel = nettyChannelBuilder.build(); SmartContractSupportGrpc.SmartContractSupportStub smartContractSupportStub = SmartContractSupportGrpc.newStub(managedChannel); receiveObserver = new StreamObserver<SmartContractShim.SmartContractMessage>() { @Override public void onNext(SmartContractShim.SmartContractMessage message) { queue.add(message); } @Override public void onError(Throwable throwable) { } @Override public void onCompleted() { managedChannel.shutdown(); } }; sendObserver = smartContractSupportStub.register(receiveObserver); }
Example #16
Source File: ConnectionDetector.java From mirror with Apache License 2.0 | 5 votes |
public static void main(String[] args) throws Exception { ChannelFactory cf = () -> NettyChannelBuilder.forAddress("shaberma-ld1", 49172).negotiationType(NegotiationType.PLAINTEXT).build(); while (true) { new Impl(cf).blockUntilConnected(); System.out.println("CONNECTED"); Thread.sleep(5000); } }
Example #17
Source File: MutinyGrpcServiceWithSSLTest.java From quarkus with Apache License 2.0 | 5 votes |
@Override @BeforeEach public void init() throws Exception { SslContext sslcontext = GrpcSslContexts.forClient() .trustManager(createTrustAllTrustManager()) .build(); channel = NettyChannelBuilder.forAddress("localhost", 9000) .sslContext(sslcontext) .build(); }
Example #18
Source File: RegularGrpcServiceWithSSLFromClasspathTest.java From quarkus with Apache License 2.0 | 5 votes |
@Override @BeforeEach public void init() throws Exception { SslContext sslcontext = GrpcSslContexts.forClient() .trustManager(createTrustAllTrustManager()) .build(); channel = NettyChannelBuilder.forAddress("localhost", 9000) .sslContext(sslcontext) .build(); }
Example #19
Source File: LoadBalanceContextBuilder.java From servicecomb-pack with Apache License 2.0 | 5 votes |
private ManagedChannel buildChannel(String address, Optional<SslContext> sslContext) { if (sslContext.isPresent()) { return NettyChannelBuilder.forTarget(address) .negotiationType(NegotiationType.TLS) .sslContext(sslContext.get()) .build(); } else { return ManagedChannelBuilder .forTarget(address).usePlaintext() .build(); } }
Example #20
Source File: GoogleAuthUtils.java From bazel with Apache License 2.0 | 5 votes |
/** * Create a new gRPC {@link ManagedChannel}. * * @throws IOException in case the channel can't be constructed. */ public static ManagedChannel newChannel( String target, String proxy, AuthAndTLSOptions options, @Nullable List<ClientInterceptor> interceptors) throws IOException { Preconditions.checkNotNull(target); Preconditions.checkNotNull(options); SslContext sslContext = isTlsEnabled(target) ? createSSlContext( options.tlsCertificate, options.tlsClientCertificate, options.tlsClientKey) : null; String targetUrl = convertTargetScheme(target); try { NettyChannelBuilder builder = newNettyChannelBuilder(targetUrl, proxy) .negotiationType( isTlsEnabled(target) ? NegotiationType.TLS : NegotiationType.PLAINTEXT); if (interceptors != null) { builder.intercept(interceptors); } if (sslContext != null) { builder.sslContext(sslContext); if (options.tlsAuthorityOverride != null) { builder.overrideAuthority(options.tlsAuthorityOverride); } } return builder.build(); } catch (RuntimeException e) { // gRPC might throw all kinds of RuntimeExceptions: StatusRuntimeException, // IllegalStateException, NullPointerException, ... String message = "Failed to connect to '%s': %s"; throw new IOException(String.format(message, targetUrl, e.getMessage())); } }
Example #21
Source File: GRPCClient.java From skywalking with Apache License 2.0 | 5 votes |
@Override public void connect() { if (sslContext == null) { channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build(); return; } channel = NettyChannelBuilder.forAddress(host, port).sslContext(sslContext).build(); }
Example #22
Source File: AlphaIntegrationWithSSLTest.java From servicecomb-pack with Apache License 2.0 | 5 votes |
@BeforeClass public static void setupClientChannel() { clientChannel = NettyChannelBuilder.forAddress("localhost", port) .negotiationType(NegotiationType.TLS) .sslContext(getSslContext()) .build(); }
Example #23
Source File: ControllerImpl.java From pravega with Apache License 2.0 | 5 votes |
/** * Creates a new instance of the Controller client class. * @param channelBuilder The channel builder to connect to the service instance. * @param config The configuration for this client implementation. * @param executor The executor service to be used internally. */ @VisibleForTesting public ControllerImpl(ManagedChannelBuilder<?> channelBuilder, final ControllerImplConfig config, final ScheduledExecutorService executor) { Preconditions.checkNotNull(channelBuilder, "channelBuilder"); this.executor = executor; this.retryConfig = createRetryConfig(config); if (config.getClientConfig().isEnableTlsToController()) { log.debug("Setting up a SSL/TLS channel builder"); SslContextBuilder sslContextBuilder; String trustStore = config.getClientConfig().getTrustStore(); sslContextBuilder = GrpcSslContexts.forClient(); if (!Strings.isNullOrEmpty(trustStore)) { sslContextBuilder = sslContextBuilder.trustManager(new File(trustStore)); } try { channelBuilder = ((NettyChannelBuilder) channelBuilder).sslContext(sslContextBuilder.build()) .negotiationType(NegotiationType.TLS); } catch (SSLException e) { throw new CompletionException(e); } } else { log.debug("Using a plaintext channel builder"); channelBuilder = ((NettyChannelBuilder) channelBuilder).negotiationType(NegotiationType.PLAINTEXT); } // Trace channel. channelBuilder = channelBuilder.intercept(RPCTracingHelpers.getClientInterceptor()); // Create Async RPC client. this.channel = channelBuilder.build(); this.client = getClientWithCredentials(config); this.timeoutMillis = config.getTimeoutMillis(); }
Example #24
Source File: GeoWaveGrpcTestClient.java From geowave with Apache License 2.0 | 5 votes |
public GeoWaveGrpcTestClient(final NettyChannelBuilder channelBuilder) { channel = channelBuilder.build(); vectorBlockingStub = VectorGrpc.newBlockingStub(channel); vectorAsyncStub = VectorGrpc.newStub(channel); coreCliBlockingStub = CoreCliGrpc.newBlockingStub(channel); coreMapreduceBlockingStub = CoreMapreduceGrpc.newBlockingStub(channel); analyticMapreduceBlockingStub = AnalyticMapreduceGrpc.newBlockingStub(channel); coreStoreBlockingStub = CoreStoreGrpc.newBlockingStub(channel); coreIngestBlockingStub = CoreIngestGrpc.newBlockingStub(channel); cliGeoserverBlockingStub = CliGeoserverGrpc.newBlockingStub(channel); analyticSparkBlockingStub = AnalyticSparkGrpc.newBlockingStub(channel); }
Example #25
Source File: HelloWorldClient.java From grpc-proxy with Apache License 2.0 | 5 votes |
private HelloWorldClient(String host, int port, TlsContext tls) throws SSLException { this.eventLoopGroup = Netty.newWorkerEventLoopGroup(); this.channel = NettyChannelBuilder.forAddress(host, port) .eventLoopGroup(eventLoopGroup) .channelType(Netty.clientChannelType()) .sslContext(tls.toClientContext()) .build(); this.blockingStub = GreeterGrpc.newBlockingStub(channel); }
Example #26
Source File: DeliverClient.java From julongchain with Apache License 2.0 | 5 votes |
@Override public void send(Common.Envelope envelope, StreamObserver<Ab.DeliverResponse> responseObserver) { managedChannel = NettyChannelBuilder.forAddress(host, port).maxInboundMessageSize(CommConstant.MAX_GRPC_MESSAGE_SIZE) .usePlaintext().build(); AtomicBroadcastGrpc.AtomicBroadcastStub stub = AtomicBroadcastGrpc.newStub(managedChannel); StreamObserver<Common.Envelope> envelopeStreamObserver = stub.deliver(responseObserver); envelopeStreamObserver.onNext(envelope); }
Example #27
Source File: HelloWorldClientTls.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
/** * Construct client connecting to HelloWorld server at {@code host:port}. */ public HelloWorldClientTls(String host, int port, SslContext sslContext) throws SSLException { this(NettyChannelBuilder.forAddress(host, port) .negotiationType(NegotiationType.TLS) .sslContext(sslContext) .build()); }
Example #28
Source File: ADAMproWrapper.java From cineast with MIT License | 5 votes |
public ADAMproWrapper() { DatabaseConfig config = Config.sharedConfig().getDatabase(); this.channel = NettyChannelBuilder.forAddress(config.getHost(), config.getPort()) .maxMessageSize(maxMessageSize).usePlaintext(config.getPlaintext()).build(); this.definitionStub = AdamDefinitionGrpc.newFutureStub(channel); this.searchStub = AdamSearchGrpc.newFutureStub(channel); this.streamSearchStub = AdamSearchGrpc.newStub(channel); }
Example #29
Source File: Main.java From cloud-pubsub-samples-java with Apache License 2.0 | 5 votes |
public static void main(final String[] args) throws Exception { if (args.length == 0) { System.err.println("Please specify your project name."); System.exit(1); } final String project = args[0]; ManagedChannelImpl channelImpl = NettyChannelBuilder .forAddress("pubsub.googleapis.com", 443) .negotiationType(NegotiationType.TLS) .build(); GoogleCredentials creds = GoogleCredentials.getApplicationDefault(); // Down-scope the credential to just the scopes required by the service creds = creds.createScoped(Arrays.asList("https://www.googleapis.com/auth/pubsub")); // Intercept the channel to bind the credential ExecutorService executor = Executors.newSingleThreadExecutor(); ClientAuthInterceptor interceptor = new ClientAuthInterceptor(creds, executor); Channel channel = ClientInterceptors.intercept(channelImpl, interceptor); // Create a stub using the channel that has the bound credential PublisherGrpc.PublisherBlockingStub publisherStub = PublisherGrpc.newBlockingStub(channel); ListTopicsRequest request = ListTopicsRequest.newBuilder() .setPageSize(10) .setProject("projects/" + project) .build(); ListTopicsResponse resp = publisherStub.listTopics(request); System.out.println("Found " + resp.getTopicsCount() + " topics."); for (Topic topic : resp.getTopicsList()) { System.out.println(topic.getName()); } }
Example #30
Source File: Http2NettyLocalChannelTest.java From grpc-java with Apache License 2.0 | 5 votes |
@Override protected ManagedChannel createChannel() { NettyChannelBuilder builder = NettyChannelBuilder .forAddress(new LocalAddress("in-process-1")) .negotiationType(NegotiationType.PLAINTEXT) .channelType(LocalChannel.class) .eventLoopGroup(eventLoopGroup) .flowControlWindow(65 * 1024) .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE); // Disable the default census stats interceptor, use testing interceptor instead. io.grpc.internal.TestingAccessor.setStatsEnabled(builder, false); return builder.intercept(createCensusStatsClientInterceptor()).build(); }