<commit_before>package com.digitalpetri.opcua.stack.server.tcp;

import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyPair;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import com.digitalpetri.opcua.stack.core.Stack;
import com.digitalpetri.opcua.stack.core.UaException;
import com.digitalpetri.opcua.stack.core.application.UaServer;
import com.digitalpetri.opcua.stack.core.application.services.AttributeServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.DiscoveryServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.MethodServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.MonitoredItemServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.NodeManagementServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.QueryServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.ServiceRequest;
import com.digitalpetri.opcua.stack.core.application.services.ServiceRequestHandler;
import com.digitalpetri.opcua.stack.core.application.services.ServiceResponse;
import com.digitalpetri.opcua.stack.core.application.services.SessionServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.SubscriptionServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.TestServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.ViewServiceSet;
import com.digitalpetri.opcua.stack.core.channel.ChannelConfig;
import com.digitalpetri.opcua.stack.core.channel.SecureChannel;
import com.digitalpetri.opcua.stack.core.channel.ServerSecureChannel;
import com.digitalpetri.opcua.stack.core.security.SecurityPolicy;
import com.digitalpetri.opcua.stack.core.serialization.UaRequestMessage;
import com.digitalpetri.opcua.stack.core.serialization.UaResponseMessage;
import com.digitalpetri.opcua.stack.core.types.builtin.ByteString;
import com.digitalpetri.opcua.stack.core.types.builtin.LocalizedText;
import com.digitalpetri.opcua.stack.core.types.enumerated.ApplicationType;
import com.digitalpetri.opcua.stack.core.types.enumerated.MessageSecurityMode;
import com.digitalpetri.opcua.stack.core.types.structured.ApplicationDescription;
import com.digitalpetri.opcua.stack.core.types.structured.EndpointDescription;
import com.digitalpetri.opcua.stack.core.types.structured.FindServersRequest;
import com.digitalpetri.opcua.stack.core.types.structured.FindServersResponse;
import com.digitalpetri.opcua.stack.core.types.structured.GetEndpointsRequest;
import com.digitalpetri.opcua.stack.core.types.structured.GetEndpointsResponse;
import com.digitalpetri.opcua.stack.core.types.structured.ServiceFault;
import com.digitalpetri.opcua.stack.core.types.structured.SignedSoftwareCertificate;
import com.digitalpetri.opcua.stack.core.types.structured.UserTokenPolicy;
import com.digitalpetri.opcua.stack.core.util.DigestUtil;
import com.digitalpetri.opcua.stack.server.Endpoint;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UaTcpServer implements UaServer {

    /**
     * The {@link AttributeKey} that maps to the {@link Channel} bound to a {@link ServerSecureChannel}.
     */
    public static AttributeKey<Channel> BoundChannelKey = AttributeKey.valueOf("bound-channel");

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final AtomicLong channelIds = new AtomicLong();
    private final AtomicLong tokenIds = new AtomicLong();

    private final Map<Class<? extends UaRequestMessage>, ServiceRequestHandler<UaRequestMessage, UaResponseMessage>>
            handlers = Maps.newConcurrentMap();

    private final Map<Long, ServerSecureChannel> secureChannels = Maps.newConcurrentMap();

    private final ListMultimap<Long, ServiceResponse> responseQueues =
            Multimaps.synchronizedListMultimap(ArrayListMultimap.create());

    private final List<Endpoint> endpoints = Lists.newCopyOnWriteArrayList();
    private final Set<String> discoveryUrls = Sets.newConcurrentHashSet();

    private final HashedWheelTimer wheelTimer = Stack.WHEEL_TIMER;
    private final Map<Long, Timeout> timeouts = Maps.newConcurrentMap();

    private final LocalizedText applicationName;
    private final String applicationUri;
    private final String productUri;
    private final Certificate certificate;
    private final KeyPair keyPair;
    private final ExecutorService executor;
    private final List<UserTokenPolicy> userTokenPolicies;
    private final List<SignedSoftwareCertificate> softwareCertificates;
    private final ChannelConfig channelConfig;

    public UaTcpServer(LocalizedText applicationName,
                       String applicationUri,
                       String productUri,
                       Certificate certificate,
                       KeyPair keyPair,
                       ExecutorService executor,
                       List<UserTokenPolicy> userTokenPolicies,
                       List<SignedSoftwareCertificate> softwareCertificates,
                       ChannelConfig channelConfig) {

        this.applicationName = applicationName;
        this.applicationUri = applicationUri;
        this.productUri = productUri;
        this.certificate = certificate;
        this.keyPair = keyPair;
        this.executor = executor;
        this.userTokenPolicies = userTokenPolicies;
        this.softwareCertificates = softwareCertificates;
        this.channelConfig = channelConfig;

        addServiceSet(new DefaultDiscoveryServiceSet());

        addServiceSet(new AttributeServiceSet() {});
        addServiceSet(new MethodServiceSet() {});
        addServiceSet(new MonitoredItemServiceSet() {});
        addServiceSet(new NodeManagementServiceSet() {});
        addServiceSet(new QueryServiceSet() {});
        addServiceSet(new SessionServiceSet() {});
        addServiceSet(new SubscriptionServiceSet() {});
        addServiceSet(new TestServiceSet() {});
        addServiceSet(new ViewServiceSet() {});
    }

    @Override
    public void startup() {
        List<Endpoint> validEndpoints = endpoints.stream()
                .filter(e -> e.getSecurityPolicy() == SecurityPolicy.None || certificate != null)
                .collect(Collectors.toList());

        for (Endpoint endpoint : validEndpoints) {
            try {
                URI endpointUri = endpoint.getEndpointUri();
                String address = endpoint.getBindAddress().orElse(endpointUri.getHost());

                SocketServer socketServer = SocketServer.boundTo(address, endpointUri.getPort());
                socketServer.addServer(this);

                logger.info("{} {}/{} bound to {}.",
                        endpoint.getEndpointUri(), endpoint.getSecurityPolicy(),
                        endpoint.getMessageSecurity(), socketServer.getLocalAddress());

                discoveryUrls.add(endpointUri.toString());
            } catch (Exception e) {
                logger.error("Error binding {}: {}.", endpoint, e.getMessage(), e);
            }
        }
    }

    @Override<commit_msg>Logging tweaks.<commit_after>package com.digitalpetri.opcua.stack.server.tcp;

import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyPair;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import com.digitalpetri.opcua.stack.core.Stack;
import com.digitalpetri.opcua.stack.core.UaException;
import com.digitalpetri.opcua.stack.core.application.UaServer;
import com.digitalpetri.opcua.stack.core.application.services.AttributeServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.DiscoveryServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.MethodServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.MonitoredItemServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.NodeManagementServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.QueryServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.ServiceRequest;
import com.digitalpetri.opcua.stack.core.application.services.ServiceRequestHandler;
import com.digitalpetri.opcua.stack.core.application.services.ServiceResponse;
import com.digitalpetri.opcua.stack.core.application.services.SessionServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.SubscriptionServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.TestServiceSet;
import com.digitalpetri.opcua.stack.core.application.services.ViewServiceSet;
import com.digitalpetri.opcua.stack.core.channel.ChannelConfig;
import com.digitalpetri.opcua.stack.core.channel.ServerSecureChannel;
import com.digitalpetri.opcua.stack.core.security.SecurityPolicy;
import com.digitalpetri.opcua.stack.core.serialization.UaRequestMessage;
import com.digitalpetri.opcua.stack.core.serialization.UaResponseMessage;
import com.digitalpetri.opcua.stack.core.types.builtin.ByteString;
import com.digitalpetri.opcua.stack.core.types.builtin.LocalizedText;
import com.digitalpetri.opcua.stack.core.types.enumerated.ApplicationType;
import com.digitalpetri.opcua.stack.core.types.enumerated.MessageSecurityMode;
import com.digitalpetri.opcua.stack.core.types.structured.ApplicationDescription;
import com.digitalpetri.opcua.stack.core.types.structured.EndpointDescription;
import com.digitalpetri.opcua.stack.core.types.structured.FindServersRequest;
import com.digitalpetri.opcua.stack.core.types.structured.FindServersResponse;
import com.digitalpetri.opcua.stack.core.types.structured.GetEndpointsRequest;
import com.digitalpetri.opcua.stack.core.types.structured.GetEndpointsResponse;
import com.digitalpetri.opcua.stack.core.types.structured.ServiceFault;
import com.digitalpetri.opcua.stack.core.types.structured.SignedSoftwareCertificate;
import com.digitalpetri.opcua.stack.core.types.structured.UserTokenPolicy;
import com.digitalpetri.opcua.stack.core.util.DigestUtil;
import com.digitalpetri.opcua.stack.server.Endpoint;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UaTcpServer implements UaServer {

    /**
     * The {@link AttributeKey} that maps to the {@link Channel} bound to a {@link ServerSecureChannel}.
     */
    public static AttributeKey<Channel> BoundChannelKey = AttributeKey.valueOf("bound-channel");

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final AtomicLong channelIds = new AtomicLong();
    private final AtomicLong tokenIds = new AtomicLong();

    private final Map<Class<? extends UaRequestMessage>, ServiceRequestHandler<UaRequestMessage, UaResponseMessage>>
            handlers = Maps.newConcurrentMap();

    private final Map<Long, ServerSecureChannel> secureChannels = Maps.newConcurrentMap();

    private final ListMultimap<Long, ServiceResponse> responseQueues =
            Multimaps.synchronizedListMultimap(ArrayListMultimap.create());

    private final List<Endpoint> endpoints = Lists.newCopyOnWriteArrayList();
    private final Set<String> discoveryUrls = Sets.newConcurrentHashSet();

    private final HashedWheelTimer wheelTimer = Stack.WHEEL_TIMER;
    private final Map<Long, Timeout> timeouts = Maps.newConcurrentMap();

    private final LocalizedText applicationName;
    private final String applicationUri;
    private final String productUri;
    private final Certificate certificate;
    private final KeyPair keyPair;
    private final ExecutorService executor;
    private final List<UserTokenPolicy> userTokenPolicies;
    private final List<SignedSoftwareCertificate> softwareCertificates;
    private final ChannelConfig channelConfig;

    public UaTcpServer(LocalizedText applicationName,
                       String applicationUri,
                       String productUri,
                       Certificate certificate,
                       KeyPair keyPair,
                       ExecutorService executor,
                       List<UserTokenPolicy> userTokenPolicies,
                       List<SignedSoftwareCertificate> softwareCertificates,
                       ChannelConfig channelConfig) {

        this.applicationName = applicationName;
        this.applicationUri = applicationUri;
        this.productUri = productUri;
        this.certificate = certificate;
        this.keyPair = keyPair;
        this.executor = executor;
        this.userTokenPolicies = userTokenPolicies;
        this.softwareCertificates = softwareCertificates;
        this.channelConfig = channelConfig;

        addServiceSet(new DefaultDiscoveryServiceSet());

        addServiceSet(new AttributeServiceSet() {});
        addServiceSet(new MethodServiceSet() {});
        addServiceSet(new MonitoredItemServiceSet() {});
        addServiceSet(new NodeManagementServiceSet() {});
        addServiceSet(new QueryServiceSet() {});
        addServiceSet(new SessionServiceSet() {});
        addServiceSet(new SubscriptionServiceSet() {});
        addServiceSet(new TestServiceSet() {});
        addServiceSet(new ViewServiceSet() {});
    }

    @Override
    public void startup() {
        List<Endpoint> validEndpoints = endpoints.stream()
                .filter(e -> e.getSecurityPolicy() == SecurityPolicy.None || certificate != null)
                .collect(Collectors.toList());

        for (Endpoint endpoint : validEndpoints) {
            try {
                URI endpointUri = endpoint.getEndpointUri();
                String address = endpoint.getBindAddress().orElse(endpointUri.getHost());

                SocketServer socketServer = SocketServer.boundTo(address, endpointUri.getPort());
                socketServer.addServer(this);

                logger.info("{} [{}/{}] bound to {}.",
                        endpoint.getEndpointUri(), endpoint.getSecurityPolicy(),
                        endpoint.getMessageSecurity(), socketServer.getLocalAddress());

                discoveryUrls.add(endpointUri.toString());
            } catch (Exception e) {
                logger.error("Error binding {}: {}.", endpoint, e.getMessage(), e);
            }
        }
    }

    @Override
{'fraction_non_alphanumeric': 0.09584459024829538, 'fraction_numerical': 0.00025730091341824265, 'mean_word_length': 4.085704939483153, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4370839', 'n_tokens_mistral': 4436, 'n_tokens_neox': 4238, 'n_words': 698}