code: /*
   * Copyright (c) 2019 the Eclipse Milo Authors
   *
   * This program and the accompanying materials are made
   * available under the terms of the Eclipse Public License 2.0
   * which is available at https://www.eclipse.org/legal/epl-2.0/
   *
   * SPDX-License-Identifier: EPL-2.0
   */
  
  package org.eclipse.milo.opcua.sdk.client.api.config;
  
  import java.util.function.Consumer;
  import java.util.function.Supplier;
  
  import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider;
  import org.eclipse.milo.opcua.stack.client.UaStackClientConfig;
  import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
  import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
  import org.eclipse.milo.opcua.stack.core.types.structured.PublishRequest;
  
  public interface OpcUaClientConfig extends UaStackClientConfig {
  
      /**
       * @return the name of the client application, as a {@link LocalizedText}.
       */
      LocalizedText getApplicationName();
  
      /**
       * @return a URI for the client's application instance. This should be the same as the URI in the client
       * certificate, if present.
       */
      String getApplicationUri();
  
      /**
       * @return the URI for the client's application product.
       */
      String getProductUri();
  
      /**
       * @return a {@link Supplier} for the session name.
       */
      Supplier<String> getSessionName();
  
      /**
       * @return the list of locale ids in priority order for localized strings
       */
      String[] getSessionLocaleIds();
  
      /**
       * @return the session timeout, in milliseconds, to request.
       */
      UInteger getSessionTimeout();
  
      /**
       * @return the maximum size for a response from the server.
       */
      UInteger getMaxResponseMessageSize();
  
      /**
       * @return the maximum number of outstanding {@link PublishRequest}s allowed at any given time.
       */
      UInteger getMaxPendingPublishRequests();
  
      /**
       * @return an {@link IdentityProvider} to use when activating a session.
       */
      IdentityProvider getIdentityProvider();
  
      /**
       * @return the number of consecutive keep-alive request failures allowed before a connection is determined to be in
       * error state.
       */
      UInteger getKeepAliveFailuresAllowed();
  
      /**
       * @return the interval, in milliseconds, between consecutive keep-alive requests.
       */
      UInteger getKeepAliveInterval();
  
      /**
       * @return the amount of time to wait, in milliseconds, for a keep-alive request before timing out.
       */
      UInteger getKeepAliveTimeout();
  
      /**
       * The multiplier applied to a subscription's expected keep-alive interval, used by the
       * watchdog timer to determine how "late" a keep-alive can arrive before it fires.
       *
       * @return the multiplier applied to a subscription's expected keep-alive interval.
       */
      double getSubscriptionWatchdogMultiplier();
  
      /**
       * @return a new {@link OpcUaClientConfigBuilder}.
       */
      static OpcUaClientConfigBuilder builder() {
          return new OpcUaClientConfigBuilder();
      }
  
      /**
       * Copy the values from an existing {@link OpcUaClientConfig} into a new {@link OpcUaClientConfigBuilder}. This
       * builder can be used to make any desired modifications before invoking {@link OpcUaClientConfigBuilder#build()}
       * to produce a new config.
       *
       * @param config the {@link OpcUaClientConfig} to copy from.
       * @return a {@link OpcUaClientConfigBuilder} pre-populated with values from {@code config}.
       */
      static OpcUaClientConfigBuilder copy(OpcUaClientConfig config) {
          OpcUaClientConfigBuilder builder = new OpcUaClientConfigBuilder();
  
          // UaStackClientConfig values
          builder.setEndpoint(config.getEndpoint());
          config.getKeyPair().ifPresent(builder::setKeyPair);
          config.getCertificate().ifPresent(builder::setCertificate);
          config.getCertificateChain().ifPresent(builder::setCertificateChain);
          builder.setApplicationName(config.getApplicationName());
          builder.setApplicationUri(config.getApplicationUri());
          builder.setProductUri(config.getProductUri());
          builder.setEncodingLimits(config.getEncodingLimits());
          builder.setChannelLifetime(config.getChannelLifetime());
          builder.setExecutor(config.getExecutor());
          builder.setScheduledExecutor(config.getScheduledExecutor());
          builder.setEventLoop(config.getEventLoop());
          builder.setWheelTimer(config.getWheelTimer());
          builder.setConnectTimeout(config.getConnectTimeout());
          builder.setAcknowledgeTimeout(config.getAcknowledgeTimeout());
          builder.setRequestTimeout(config.getRequestTimeout());
  
          // OpcUaClientConfig values
          builder.setSessionName(config.getSessionName());
          builder.setSessionTimeout(config.getSessionTimeout());
          builder.setRequestTimeout(config.getRequestTimeout());
          builder.setMaxResponseMessageSize(config.getMaxResponseMessageSize());
          builder.setMaxPendingPublishRequests(config.getMaxPendingPublishRequests());
          builder.setIdentityProvider(config.getIdentityProvider());
          builder.setKeepAliveFailuresAllowed(config.getKeepAliveFailuresAllowed());
          builder.setKeepAliveInterval(config.getKeepAliveInterval());
          builder.setKeepAliveTimeout(config.getKeepAliveTimeout());
          builder.setSessionLocaleIds(config.getSessionLocaleIds());
          builder.setSubscriptionWatchdogMultiplier(config.getSubscriptionWatchdogMultiplier());
  
          return builder;
      }
  
      /**
       * Copy the values from an existing {@link OpcUaClientConfig} into a new {@link OpcUaClientConfigBuilder} and then
       * submit the builder to the provided consumer for modification.
       *
       * @param config   the {@link OpcUaClientConfig} to copy from.
       * @param consumer a {@link Consumer} that may modify the builder.
       * @return a {@link OpcUaClientConfig} built from the builder provided to {@code consumer}.
       */
      static OpcUaClientConfig copy(
          OpcUaClientConfig config,
          Consumer<OpcUaClientConfigBuilder> consumer) {
  
          OpcUaClientConfigBuilder builder = copy(config);
  
          consumer.accept(builder);
  
          return builder.build();
      }
  
  }
  