001    /*
002     * Copyright 2009-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2015 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.ldap.sdk.unboundidds.monitors;
022    
023    
024    
025    import java.util.Collections;
026    import java.util.LinkedHashMap;
027    import java.util.Map;
028    
029    import com.unboundid.ldap.sdk.Entry;
030    import com.unboundid.util.NotMutable;
031    import com.unboundid.util.ThreadSafety;
032    import com.unboundid.util.ThreadSafetyLevel;
033    
034    import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
035    import static com.unboundid.util.Debug.*;
036    
037    
038    
039    /**
040     * <BLOCKQUOTE>
041     *   <B>NOTE:</B>  This class is part of the Commercial Edition of the UnboundID
042     *   LDAP SDK for Java.  It is not available for use in applications that
043     *   include only the Standard Edition of the LDAP SDK, and is not supported for
044     *   use in conjunction with non-UnboundID products.
045     * </BLOCKQUOTE>
046     * This class defines a monitor entry that provides information about the state
047     * of a replica, including the base DN, replica ID, and generation ID, as well
048     * as information about its communication with the replication server
049     * <BR><BR>
050     * The server should present a replica monitor entry for each replicated base
051     * DN.  They can be retrieved using the
052     * {@link MonitorManager#getReplicaMonitorEntries} method.  These entries
053     * provide specific methods for accessing information about the replica.
054     * Alternately, this information may be accessed using the generic API.  See the
055     * {@link MonitorManager} class documentation for an example that demonstrates
056     * the use of the generic API for accessing monitor data.
057     */
058    @NotMutable()
059    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
060    public final class ReplicaMonitorEntry
061           extends MonitorEntry
062    {
063      /**
064       * The structural object class used in replica monitor entries.
065       */
066      static final String REPLICA_MONITOR_OC =
067           "ds-replica-monitor-entry";
068    
069    
070    
071      /**
072       * The name of the attribute that contains the base DNs for the replicated
073       * data.
074       */
075      private static final String ATTR_BASE_DN = "base-dn";
076    
077    
078    
079      /**
080       * The name of the attribute that contains the address and port of the
081       * replication server to which the replica is connected.
082       */
083      private static final String ATTR_CONNECTED_TO =
084           "connected-to";
085    
086    
087    
088      /**
089       * The name of the attribute that provides information about the current
090       * receive window size.
091       */
092      private static final String ATTR_CURRENT_RECEIVE_WINDOW_SIZE =
093           "current-rcv-window";
094    
095    
096    
097      /**
098       * The name of the attribute that provides information about the current send
099       * window size.
100       */
101      private static final String ATTR_CURRENT_SEND_WINDOW_SIZE =
102           "current-send-window";
103    
104    
105    
106      /**
107       * The name of the attribute that provides the generation ID for the replica.
108       */
109      private static final String ATTR_GENERATION_ID = "generation-id";
110    
111    
112    
113      /**
114       * The name of the attribute that provides information about the number of
115       * times the connection to the replication server has been lost.
116       */
117      private static final String ATTR_LOST_CONNECTIONS = "lost-connections";
118    
119    
120    
121      /**
122       * The name of the attribute that provides information about the maximum
123       * receive window size.
124       */
125      private static final String ATTR_MAX_RECEIVE_WINDOW_SIZE =
126           "max-rcv-window";
127    
128    
129    
130      /**
131       * The name of the attribute that provides information about the maximum send
132       * window size.
133       */
134      private static final String ATTR_MAX_SEND_WINDOW_SIZE =
135           "max-send-window";
136    
137    
138    
139      /**
140       * The name of the attribute that provides information about the number of
141       * pending updates which are currently being processed by the Directory Server
142       * and have not yet been sent to the replication server.
143       */
144      private static final String ATTR_PENDING_UPDATES = "pending-updates";
145    
146    
147    
148      /**
149       * The name of the attribute that provides information about the number of
150       * updates received from the replication server for this replica.
151       */
152      private static final String ATTR_RECEIVED_UPDATES = "received-updates";
153    
154    
155    
156      /**
157       * The name of the attribute that provides the replica ID for this replica.
158       */
159      private static final String ATTR_REPLICA_ID = "replica-id";
160    
161    
162    
163      /**
164       * The name of the attribute that provides information about the number of
165       * updates that were replayed after resolving a modify conflict.
166       */
167      private static final String ATTR_RESOLVED_MODIFY_CONFLICTS =
168           "resolved-modify-conflicts";
169    
170    
171    
172      /**
173       * The name of the attribute that provides information about the number of
174       * updates that were replayed after resolving a naming conflict.
175       */
176      private static final String ATTR_RESOLVED_NAMING_CONFLICTS =
177           "resolved-naming-conflicts";
178    
179    
180    
181      /**
182       * The name of the attribute that provides information about the number of
183       * updates sent to the replication server from this replica.
184       */
185      private static final String ATTR_SENT_UPDATES = "sent-updates";
186    
187    
188    
189      /**
190       * The name of the attribute that indicates whether SSL is used when
191       * communicating with the replication server.
192       */
193      private static final String ATTR_SSL_ENCRYPTION = "ssl-encryption";
194    
195    
196    
197      /**
198       * The name of the attribute that provides information about the number of
199       * updates that have been successfully replayed with no problems.
200       */
201      private static final String ATTR_SUCCESSFUL_REPLAYED = "replayed-updates-ok";
202    
203    
204    
205      /**
206       * The name of the attribute that provides information about the total number
207       * of updates that have been replayed in some form.
208       */
209      private static final String ATTR_TOTAL_REPLAYED = "replayed-updates";
210    
211    
212    
213      /**
214       * The name of the attribute that provides information about the number of
215       * updates that could not be replayed because of an unresolved naming
216       * conflict.
217       */
218      private static final String ATTR_UNRESOLVED_NAMING_CONFLICTS =
219           "unresolved-naming-conflicts";
220    
221    
222    
223      /**
224       * The serial version UID for this serializable class.
225       */
226      private static final long serialVersionUID = -9164207693317460579L;
227    
228    
229    
230      // Indicates whether the replica uses SSL when communicating with the
231      // replication server.
232      private final Boolean useSSL;
233    
234      // The current receive window size.
235      private final Long currentReceiveWindowSize;
236    
237      // The current send window size.
238      private final Long currentSendWindowSize;
239    
240      // The number of lost connections.
241      private final Long lostConnections;
242    
243      // The maximum receive window size.
244      private final Long maxReceiveWindowSize;
245    
246      // The maximum send window size.
247      private final Long maxSendWindowSize;
248    
249      // The number of pending updates that haven't been sent to the replication
250      // server.
251      private final Long pendingUpdates;
252    
253      // The number of updates received from the replication server.
254      private final Long receivedUpdates;
255    
256      // The number of updates replayed after resolving a modify conflict.
257      private final Long replayedAfterModifyConflict;
258    
259      // The number of updates replayed after resolving a naming conflict.
260      private final Long replayedAfterNamingConflict;
261    
262      // The port number of the replication server.
263      private final Long replicationServerPort;
264    
265      // The number of updates sent to the replication server.
266      private final Long sentUpdates;
267    
268      // The number of updates replayed successfully.
269      private final Long successfullyReplayed;
270    
271      // The total number of updates replayed.
272      private final Long totalReplayed;
273    
274      // The number of unresolved naming conflicts that could not be successfully
275      // replayed.
276      private final Long unresolvedNamingConflicts;
277    
278      // The base DN for the replicated data.
279      private final String baseDN;
280    
281      // The generation ID for the replicated data.
282      private final String generationID;
283    
284      // The replica ID for the replica.
285      private final String replicaID;
286    
287      // The address of the replication server.
288      private final String replicationServerAddress;
289    
290    
291    
292      /**
293       * Creates a new replica monitor entry from the provided entry.
294       *
295       * @param  entry  The entry to be parsed as a replica monitor entry.  It must
296       *                not be {@code null}.
297       */
298      public ReplicaMonitorEntry(final Entry entry)
299      {
300        super(entry);
301    
302        useSSL                      = getBoolean(ATTR_SSL_ENCRYPTION);
303        lostConnections             = getLong(ATTR_LOST_CONNECTIONS);
304        receivedUpdates             = getLong(ATTR_RECEIVED_UPDATES);
305        sentUpdates                 = getLong(ATTR_SENT_UPDATES);
306        pendingUpdates              = getLong(ATTR_PENDING_UPDATES);
307        totalReplayed               = getLong(ATTR_TOTAL_REPLAYED);
308        successfullyReplayed        = getLong(ATTR_SUCCESSFUL_REPLAYED);
309        replayedAfterModifyConflict = getLong(ATTR_RESOLVED_MODIFY_CONFLICTS);
310        replayedAfterNamingConflict = getLong(ATTR_RESOLVED_NAMING_CONFLICTS);
311        unresolvedNamingConflicts   = getLong(ATTR_UNRESOLVED_NAMING_CONFLICTS);
312        currentReceiveWindowSize    = getLong(ATTR_CURRENT_RECEIVE_WINDOW_SIZE);
313        currentSendWindowSize       = getLong(ATTR_CURRENT_SEND_WINDOW_SIZE);
314        maxReceiveWindowSize        = getLong(ATTR_MAX_RECEIVE_WINDOW_SIZE);
315        maxSendWindowSize           = getLong(ATTR_MAX_SEND_WINDOW_SIZE);
316        baseDN                      = getString(ATTR_BASE_DN);
317        generationID                = getString(ATTR_GENERATION_ID);
318        replicaID                   = getString(ATTR_REPLICA_ID);
319    
320        String addr = null;
321        Long   port = null;
322        final String connectedTo = getString(ATTR_CONNECTED_TO);
323        if (connectedTo != null)
324        {
325          try
326          {
327            final int colonPos = connectedTo.indexOf(':');
328            if (colonPos > 0)
329            {
330              addr = connectedTo.substring(0, colonPos);
331              port = Long.parseLong(connectedTo.substring(colonPos+1));
332            }
333          }
334          catch (Exception e)
335          {
336            debugException(e);
337            addr = null;
338            port = null;
339          }
340        }
341    
342        replicationServerAddress = addr;
343        replicationServerPort    = port;
344      }
345    
346    
347    
348      /**
349       * Retrieves the base DN for this replica.
350       *
351       * @return  The base DN for this replica, or {@code null} if it was not
352       *          included in the monitor entry.
353       */
354      public String getBaseDN()
355      {
356        return baseDN;
357      }
358    
359    
360    
361      /**
362       * Retrieves the replica ID for this replica.
363       *
364       * @return  The replica ID for this replica, or {@code null} if it was not
365       *          included in the monitor entry.
366       */
367      public String getReplicaID()
368      {
369        return replicaID;
370      }
371    
372    
373    
374      /**
375       * Retrieves the generation ID for this replica.
376       *
377       * @return  The generation ID for this replica, or {@code null} if it was not
378       *          included in the monitor entry.
379       */
380      public String getGenerationID()
381      {
382        return generationID;
383      }
384    
385    
386    
387      /**
388       * Retrieves the address of the replication server to which this replica is
389       * connected.
390       *
391       * @return  The address of the replication server to which this replica is
392       *          connected, or {@code null} if it was not included in the monitor
393       *          entry.
394       */
395      public String getReplicationServerAddress()
396      {
397        return replicationServerAddress;
398      }
399    
400    
401    
402      /**
403       * Retrieves the port number of the replication server to which this replica
404       * is connected.
405       *
406       * @return  The port number of the replication server to which this replica is
407       *          connected, or {@code null} if it was not included in the monitor
408       *          entry.
409       */
410      public Long getReplicationServerPort()
411      {
412        return replicationServerPort;
413      }
414    
415    
416    
417      /**
418       * Indicates whether this replica uses SSL when communicating with the
419       * replication server.
420       *
421       * @return  {@code Boolean.TRUE} if this replica uses SSL when communicating
422       *          with the replication server, {@code Booelan.FALSE} if it does not
423       *          use SSL, or {@code null} if it was not included in the monitor
424       *          entry.
425       */
426      public Boolean useSSL()
427      {
428        return useSSL;
429      }
430    
431    
432    
433      /**
434       * Retrieves the number of times this replica has lost the connection to a
435       * replication server.
436       *
437       * @return  The number of times this replica has lost the connection to a
438       *          replication server, or {@code null} if it was not included in the
439       *          monitor entry.
440       */
441      public Long getLostConnections()
442      {
443        return lostConnections;
444      }
445    
446    
447    
448      /**
449       * Retrieves the number of updates that this replica has received from the
450       * replication server.
451       *
452       * @return  The number of updates that this replica has received from the
453       *          replication server, or {@code null} if it was not included in the
454       *          monitor entry.
455       */
456      public Long getReceivedUpdates()
457      {
458        return receivedUpdates;
459      }
460    
461    
462    
463      /**
464       * Retrieves the number of updates that this replica has sent to the
465       * replication server.
466       *
467       * @return  The number of updates that this replica has sent to the
468       *          replication server, or {@code null} if it was not included in the
469       *          monitor entry.
470       */
471      public Long getSentUpdates()
472      {
473        return sentUpdates;
474      }
475    
476    
477    
478      /**
479       * Retrieves the number of updates that are currently in progress in the
480       * Directory Server and have not yet been sent to the replication server.
481       *
482       * @return  The number of updates that are currently in progress in the
483       *          Directory Server and have not yet been sent to the replication
484       *          server, or {@code null} if it was not included in the monitor
485       *          entry.
486       */
487      public Long getPendingUpdates()
488      {
489        return pendingUpdates;
490      }
491    
492    
493    
494      /**
495       * Retrieves the total number of updates that have been replayed in this
496       * replica.
497       *
498       * @return  The total number of updates that have been replayed in this
499       *          replica, or {@code null} if it was not included in the monitor
500       *          entry.
501       */
502      public Long getTotalUpdatesReplayed()
503      {
504        return totalReplayed;
505      }
506    
507    
508    
509      /**
510       * Retrieves the number of updates that have been successfully replayed in
511       * this replica without conflicts.
512       *
513       * @return  The number of updates that have been successfully replayed in this
514       *          replica without conflicts, or {@code null} if it was not included
515       *          in the monitor entry.
516       */
517      public Long getUpdatesSuccessfullyReplayed()
518      {
519        return successfullyReplayed;
520      }
521    
522    
523    
524      /**
525       * Retrieves the number of updates that have been replayed in this replica
526       * after automatically resolving a modify conflict.
527       *
528       * @return  The number of updates that have been replayed in this replica
529       *          after automatically resolving a modify conflict, or {@code null}
530       *          if it was not included in the monitor entry.
531       */
532      public Long getUpdatesReplayedAfterModifyConflict()
533      {
534        return replayedAfterModifyConflict;
535      }
536    
537    
538    
539      /**
540       * Retrieves the number of updates that have been replayed in this replica
541       * after automatically resolving a naming conflict.
542       *
543       * @return  The number of updates that have been replayed in this replica
544       *          after automatically resolving a naming conflict, or {@code null}
545       *          if it was not included in the monitor entry.
546       */
547      public Long getUpdatesReplayedAfterNamingConflict()
548      {
549        return replayedAfterNamingConflict;
550      }
551    
552    
553    
554      /**
555       * Retrieves the number of updates that could not be replayed as a result of a
556       * naming conflict that could not be automatically resolved.
557       *
558       * @return  The number of updates that could not be replayed as a result of a
559       *          naming conflict that could not be automatically resolved, or
560       *          {@code null} if it was not included in the monitor entry.
561       */
562      public Long getUnresolvedNamingConflicts()
563      {
564        return unresolvedNamingConflicts;
565      }
566    
567    
568    
569      /**
570       * Retrieves the current receive window size for this replica.
571       *
572       * @return  The current receive window size for this replica, or {@code null}
573       *          if it was not included in the monitor entry.
574       */
575      public Long getCurrentReceiveWindowSize()
576      {
577        return currentReceiveWindowSize;
578      }
579    
580    
581    
582      /**
583       * Retrieves the current send window size for this replica.
584       *
585       * @return  The current send window size for this replica, or {@code null} if
586       *          it was not included in the monitor entry.
587       */
588      public Long getCurrentSendWindowSize()
589      {
590        return currentSendWindowSize;
591      }
592    
593    
594    
595      /**
596       * Retrieves the maximum receive window size for this replica.
597       *
598       * @return  The maximum receive window size for this replica, or {@code null}
599       *          if it was not included in the monitor entry.
600       */
601      public Long getMaximumReceiveWindowSize()
602      {
603        return maxReceiveWindowSize;
604      }
605    
606    
607    
608      /**
609       * Retrieves the maximum send window size for this replica.
610       *
611       * @return  The maximum send window size for this replica, or {@code null} if
612       *          it was not included in the monitor entry.
613       */
614      public Long getMaximumSendWindowSize()
615      {
616        return maxSendWindowSize;
617      }
618    
619    
620    
621      /**
622       * {@inheritDoc}
623       */
624      @Override()
625      public String getMonitorDisplayName()
626      {
627        return INFO_REPLICA_MONITOR_DISPNAME.get();
628      }
629    
630    
631    
632      /**
633       * {@inheritDoc}
634       */
635      @Override()
636      public String getMonitorDescription()
637      {
638        return INFO_REPLICA_MONITOR_DESC.get();
639      }
640    
641    
642    
643      /**
644       * {@inheritDoc}
645       */
646      @Override()
647      public Map<String,MonitorAttribute> getMonitorAttributes()
648      {
649        final LinkedHashMap<String,MonitorAttribute> attrs =
650             new LinkedHashMap<String,MonitorAttribute>();
651    
652        if (baseDN != null)
653        {
654          addMonitorAttribute(attrs,
655               ATTR_BASE_DN,
656               INFO_REPLICA_DISPNAME_BASE_DN.get(),
657               INFO_REPLICA_DESC_BASE_DN.get(),
658               baseDN);
659        }
660    
661        if (replicaID != null)
662        {
663          addMonitorAttribute(attrs,
664               ATTR_REPLICA_ID,
665               INFO_REPLICA_DISPNAME_REPLICA_ID.get(),
666               INFO_REPLICA_DESC_REPLICA_ID.get(),
667               replicaID);
668        }
669    
670        if (generationID != null)
671        {
672          addMonitorAttribute(attrs,
673               ATTR_GENERATION_ID,
674               INFO_REPLICA_DISPNAME_GENERATION_ID.get(),
675               INFO_REPLICA_DESC_GENERATION_ID.get(),
676               generationID);
677        }
678    
679        if (replicationServerAddress != null)
680        {
681          addMonitorAttribute(attrs,
682               ATTR_CONNECTED_TO,
683               INFO_REPLICA_DISPNAME_CONNECTED_TO.get(),
684               INFO_REPLICA_DESC_CONNECTED_TO.get(),
685               replicationServerAddress + ':' + replicationServerPort);
686        }
687    
688        if (useSSL != null)
689        {
690          addMonitorAttribute(attrs,
691               ATTR_SSL_ENCRYPTION,
692               INFO_REPLICA_DISPNAME_USE_SSL.get(),
693               INFO_REPLICA_DESC_USE_SSL.get(),
694               useSSL);
695        }
696    
697        if (lostConnections != null)
698        {
699          addMonitorAttribute(attrs,
700               ATTR_LOST_CONNECTIONS,
701               INFO_REPLICA_DISPNAME_LOST_CONNECTIONS.get(),
702               INFO_REPLICA_DESC_LOST_CONNECTIONS.get(),
703               lostConnections);
704        }
705    
706        if (receivedUpdates != null)
707        {
708          addMonitorAttribute(attrs,
709               ATTR_RECEIVED_UPDATES,
710               INFO_REPLICA_DISPNAME_RECEIVED_UPDATES.get(),
711               INFO_REPLICA_DESC_RECEIVED_UPDATES.get(),
712               receivedUpdates);
713        }
714    
715        if (sentUpdates != null)
716        {
717          addMonitorAttribute(attrs,
718               ATTR_SENT_UPDATES,
719               INFO_REPLICA_DISPNAME_SENT_UPDATES.get(),
720               INFO_REPLICA_DESC_SENT_UPDATES.get(),
721               sentUpdates);
722        }
723    
724        if (pendingUpdates != null)
725        {
726          addMonitorAttribute(attrs,
727               ATTR_PENDING_UPDATES,
728               INFO_REPLICA_DISPNAME_PENDING_UPDATES.get(),
729               INFO_REPLICA_DESC_PENDING_UPDATES.get(),
730               pendingUpdates);
731        }
732    
733        if (totalReplayed != null)
734        {
735          addMonitorAttribute(attrs,
736               ATTR_TOTAL_REPLAYED,
737               INFO_REPLICA_DISPNAME_TOTAL_REPLAYED.get(),
738               INFO_REPLICA_DESC_TOTAL_REPLAYED.get(),
739               totalReplayed);
740        }
741    
742        if (successfullyReplayed != null)
743        {
744          addMonitorAttribute(attrs,
745               ATTR_SUCCESSFUL_REPLAYED,
746               INFO_REPLICA_DISPNAME_SUCCESSFUL_REPLAYED.get(),
747               INFO_REPLICA_DESC_SUCCESSFUL_REPLAYED.get(),
748               successfullyReplayed);
749        }
750    
751        if (replayedAfterModifyConflict != null)
752        {
753          addMonitorAttribute(attrs,
754               ATTR_RESOLVED_MODIFY_CONFLICTS,
755               INFO_REPLICA_DISPNAME_RESOLVED_MODIFY_CONFLICTS.get(),
756               INFO_REPLICA_DESC_RESOLVED_MODIFY_CONFLICTS.get(),
757               replayedAfterModifyConflict);
758        }
759    
760        if (replayedAfterNamingConflict != null)
761        {
762          addMonitorAttribute(attrs,
763               ATTR_RESOLVED_NAMING_CONFLICTS,
764               INFO_REPLICA_DISPNAME_RESOLVED_NAMING_CONFLICTS.get(),
765               INFO_REPLICA_DESC_RESOLVED_NAMING_CONFLICTS.get(),
766               replayedAfterNamingConflict);
767        }
768    
769        if (unresolvedNamingConflicts != null)
770        {
771          addMonitorAttribute(attrs,
772               ATTR_UNRESOLVED_NAMING_CONFLICTS,
773               INFO_REPLICA_DISPNAME_UNRESOLVED_NAMING_CONFLICTS.get(),
774               INFO_REPLICA_DESC_UNRESOLVED_NAMING_CONFLICTS.get(),
775               unresolvedNamingConflicts);
776        }
777    
778        if (currentReceiveWindowSize != null)
779        {
780          addMonitorAttribute(attrs,
781               ATTR_CURRENT_RECEIVE_WINDOW_SIZE,
782               INFO_REPLICA_DISPNAME_CURRENT_RECEIVE_WINDOW_SIZE.get(),
783               INFO_REPLICA_DESC_CURRENT_RECEIVE_WINDOW_SIZE.get(),
784               currentReceiveWindowSize);
785        }
786    
787        if (currentSendWindowSize != null)
788        {
789          addMonitorAttribute(attrs,
790               ATTR_CURRENT_SEND_WINDOW_SIZE,
791               INFO_REPLICA_DISPNAME_CURRENT_SEND_WINDOW_SIZE.get(),
792               INFO_REPLICA_DESC_CURRENT_SEND_WINDOW_SIZE.get(),
793               currentSendWindowSize);
794        }
795    
796        if (maxReceiveWindowSize != null)
797        {
798          addMonitorAttribute(attrs,
799               ATTR_MAX_RECEIVE_WINDOW_SIZE,
800               INFO_REPLICA_DISPNAME_MAX_RECEIVE_WINDOW_SIZE.get(),
801               INFO_REPLICA_DESC_MAX_RECEIVE_WINDOW_SIZE.get(),
802               maxReceiveWindowSize);
803        }
804    
805        if (maxSendWindowSize != null)
806        {
807          addMonitorAttribute(attrs,
808               ATTR_MAX_SEND_WINDOW_SIZE,
809               INFO_REPLICA_DISPNAME_MAX_SEND_WINDOW_SIZE.get(),
810               INFO_REPLICA_DESC_MAX_SEND_WINDOW_SIZE.get(),
811               maxSendWindowSize);
812        }
813    
814        return Collections.unmodifiableMap(attrs);
815      }
816    }