Context:
# -*- encoding: utf-8 -*-
"""
Local server.

`H2OLocalServer` allows to start H2O servers on your local machine:
    hs = H2OLocalServer.start() : start a new local server
    hs.is_running() : check if the server is running
    hs.shutdown() : shut down the server

:copyright: (c) 2016 H2O.ai
:license:   Apache License Version 2.0 (see LICENSE for details)
"""
from __future__ import absolute_import, division, print_function, unicode_literals

import atexit
import os
import subprocess
import sys
import tempfile
import time
from random import choice
from sysconfig import get_config_var
from warnings import warn

from h2o.exceptions import H2OServerError, H2OStartupError, H2OValueError
from h2o.utils.compatibility import *  # NOQA
from h2o.utils.typechecks import assert_is_type, assert_satisfies, BoundInt, I, is_type

__all__ = ("H2OLocalServer", )

class H2OLocalServer(object):
    """
    Handle to an H2O server launched locally.

    Public interface::

        hs = H2OLocalServer.start(...)  # launch a new local H2O server
        hs.is_running()                 # check if the server is running
        hs.shutdown()                   # shut down the server
        hs.scheme                       # either "http" or "https"
        hs.ip                           # ip address of the server, typically "127.0.0.1"
        hs.port                         # port on which the server is listening

    Once started, the server will run until the script terminates, or until you call `.shutdown()` on it. Moreover,
    if the server terminates with an exception, then the server will not stop and will continue to run even after
    Python process exits. This runaway process may end up being in a bad shape (e.g. frozen), then the only way to
    terminate it is to kill the java process from the terminal.

    Alternatively, it is possible to start the server as a context manager, in which case it will be automatically
    shut down even if an exception occurs in Python (but not if the Python process is killed)::

        with H2OLocalServer.start() as hs:
            # do something with the server -- probably connect to it
    """

    _TIME_TO_START = 10  # Maximum time we wait for the server to start up (in seconds)
    _TIME_TO_KILL = 3    # Maximum time we wait for the server to shut down until we kill it (in seconds)

    @staticmethod
    def start(jar_path=None, nthreads=-1, enable_assertions=True, max_mem_size=None, min_mem_size=None,
              ice_root=None, port="54321+", verbose=True):
        """
        Start new H2O server on the local machine.

        :param jar_path: Path to the h2o.jar executable. If not given, then we will search for h2o.jar in the
            locations returned by `._jar_paths()`.
        :param nthreads: Number of threads in the thread pool. This should be related to the number of CPUs used.
            -1 means use all CPUs on the host. A positive integer specifies the number of CPUs directly.
        :param enable_assertions: If True, pass `-ea` option to the JVM.
        :param max_mem_size: Maximum heap size (jvm option Xmx), in bytes.
        :param min_mem_size: Minimum heap size (jvm option Xms), in bytes.
        :param ice_root: A directory where H2O stores its temporary files. Default location is determined by
            tempfile.mkdtemp().
        :param port: Port where to start the new server. This could be either an integer, or a string of the form
            "DDDDD+", indicating that the server should start looking for an open port starting from DDDDD and up.
        :param verbose: If True, then connection info will be printed to the stdout.

        :returns: a new H2OLocalServer instance
        """
        assert_is_type(jar_path, None, str)
        assert_is_type(port, None, int, str)
        assert_is_type(nthreads, -1, BoundInt(1, 4096))
        assert_is_type(enable_assertions, bool)
        assert_is_type(min_mem_size, None, int)
        assert_is_type(max_mem_size, None, BoundInt(1 << 25))
        assert_is_type(ice_root, None, I(str, os.path.isdir))
        if jar_path:
            assert_satisfies(jar_path, jar_path.endswith("h2o.jar"))

        if min_mem_size is not None and max_mem_size is not None and min_mem_size > max_mem_size:
            raise H2OValueError("`min_mem_size`=%d is larger than the `max_mem_size`=%d" % (min_mem_size, max_mem_size))
        if port is None: port = "54321+"
        baseport = None
        # TODO: get rid of this port gimmick and have 2 separate parameters.
        if is_type(port, str):
            if port.isdigit():
                port = int(port)
            else:
                if not(port[-1] == "+" and port[:-1].isdigit()):
                    raise H2OValueError("`port` should be of the form 'DDDD+', where D is a digit. Got: %s" % port)
                baseport = int(port[:-1])
                port = 0

        hs = H2OLocalServer()
        hs._verbose = bool(verbose)
        hs._jar_path = hs._find_jar(jar_path)
        hs._ice_root = ice_root
        if not ice_root:
            hs._ice_root = tempfile.mkdtemp()
            hs._tempdir = hs._ice_root

        if verbose: print("Attempting to start a local H2O server...")
        hs._launch_server(port=port, baseport=baseport, nthreads=int(nthreads), ea=enable_assertions,
                          mmax=max_mem_size, mmin=min_mem_size)
        if verbose: print("  Server is running at %s://%s:%d" % (hs.scheme, hs.ip, hs.port))
        atexit.register(lambda: hs.shutdown())
        return hs

    def is_running(self):
        """Return True if the server process is still running, False otherwise."""
        return self._process is not None and self._process.poll() is None

    def shutdown(self):
        """
        Shut down the server by trying to terminate/kill its process.

        First we attempt to terminate the server process gracefully (sending SIGTERM signal). However after
        _TIME_TO_KILL seconds if the process didn't shutdown, we forcefully kill it with a SIGKILL signal.
        """
        if not self._process: return
        try:
            kill_time = time.time() + self._TIME_TO_KILL
            while self._process.poll() is None and time.time() < kill_time:
                self._process.terminate()
                time.sleep(0.2)
            if self._process().poll() is None:
                self._process.kill()
                time.sleep(0.2)
            if self._verbose:
                print("Local H2O server %s:%s stopped." % (self.ip, self.port))
        except:
            pass
        self._process = None

    @property
    def scheme(self):
        """Connection scheme, 'http' or 'https'."""
        return self._scheme

    @property
    def ip(self):
        """IP address of the server."""
        return self._ip

    @property
    def port(self):
        """Port that the server is listening to."""
        return self._port

    #-------------------------------------------------------------------------------------------------------------------
    # Private
    #-------------------------------------------------------------------------------------------------------------------

    def __init__(self):
        """[Internal] please use H2OLocalServer.start() to launch a new server."""
        self._scheme = None   # "http" or "https"
        self._ip = None
        self._port = None
        self._process = None
        self._verbose = None
        self._jar_path = None
        self._ice_root = None
        self._stdout = None
        self._stderr = None
        self._tempdir = None

    def _find_jar(self, path0=None):
        """
        Return the location of an h2o.jar executable.

        :param path0: Explicitly given h2o.jar path. If provided, then we will simply check whether the file is there,
            otherwise we will search for an executable in locations returned by ._jar_paths().

        :raises H2OStartupError: if no h2o.jar executable can be found.
        """
        jar_paths = [path0] if path0 else self._jar_paths()
        searched_paths = []
        for jp in jar_paths:
            searched_paths.append(jp)
            if os.path.exists(jp):
                return jp
        raise H2OStartupError("Cannot start local server: h2o.jar not found. Paths searched:\n" +
                              "".join("    %s\n" % s for s in searched_paths))

    @staticmethod
    def _jar_paths():
        """Produce potential paths for an h2o.jar executable."""
        # Check if running from an h2o-3 src folder (or any subfolder), in which case use the freshly-built h2o.jar
        cwd_chunks = os.path.abspath(".").split(os.path.sep)
        for i in range(len(cwd_chunks), 0, -1):
            if cwd_chunks[i - 1] == "h2o-3":
                yield os.path.sep.join(cwd_chunks[:i] + ["build", "h2o.jar"])
        # Then check the backend/bin folder:
        # (the following works assuming this code is located in h2o/backend/server.py file)
        backend_dir = os.path.split(os.path.realpath(__file__))[0]
        yield os.path.join(backend_dir, "bin", "h2o.jar")

        # Then try several old locations where h2o.jar might have been installed
        prefix1 = prefix2 = sys.prefix
        # On Unix-like systems Python typically gets installed into /Library/... or /System/Library/... If one of
        # those paths is sys.prefix, then we also build its counterpart.
        if prefix1.startswith(os.path.sep + "Library"):
            prefix2 = os.path.join("", "System", prefix1)
        elif prefix1.startswith(os.path.sep + "System"):
            prefix2 = prefix1[len(os.path.join("", "System")):]
        yield os.path.join(prefix1, "h2o_jar", "h2o.jar")
        yield os.path.join(os.path.abspath(os.sep), "usr", "local", "h2o_jar", "h2o.jar")
        yield os.path.join(prefix1, "local", "h2o_jar", "h2o.jar")
        yield os.path.join(get_config_var("userbase"), "h2o_jar", "h2o.jar")
        yield os.path.join(prefix2, "h2o_jar", "h2o.jar")

    def _launch_server(self, port, baseport, mmax, mmin, ea, nthreads):
        """Actually start the h2o.jar executable (helper method for `.start()`)."""
        self._ip = "127.0.0.1"

        # Find Java and check version. (Note that subprocess.check_output returns the output as a bytes object)
        java = self._find_java()
        jver_bytes = subprocess.check_output([java, "-version"], stderr=subprocess.STDOUT)
        jver = jver_bytes.decode(encoding="utf-8", errors="ignore")
        if self._verbose:
            print("  Java Version: " + jver.strip().replace("\n", "; "))
        if "GNU libgcj" in jver:
            raise H2OStartupError("Sorry, GNU Java is not supported for H2O.\n"
                                  "Please download the latest 64-bit Java SE JDK from Oracle.")
        if "Client VM" in jver:
            warn("  You have a 32-bit version of Java. H2O works best with 64-bit Java.\n"
                 "  Please download the latest 64-bit Java SE JDK from Oracle.\n")

        if self._verbose:
            print("  Starting server from " + self._jar_path)
            print("  Ice root: " + self._ice_root)

        # Construct java command to launch the process
        cmd = [java]

        # ...add JVM options
        cmd += ["-ea"] if ea else []
        for (mq, num) in [("-Xms", mmin), ("-Xmx", mmax)]:
            if num is None: continue
            numstr = "%dG" % (num >> 30) if num == (num >> 30) << 30 else \
                     "%dM" % (num >> 20) if num == (num >> 20) << 20 else \
                     str(num)
            cmd += [mq + numstr]
        cmd += ["-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps"]
        cmd += ["-jar", self._jar_path]  # This should be the last JVM option

        # ...add H2O options
        cmd += ["-ip", self._ip]
        cmd += ["-port", str(port)] if port else []
        cmd += ["-baseport", str(baseport)] if baseport else []
        cmd += ["-ice_root", self._ice_root]
        cmd += ["-nthreads", str(nthreads)] if nthreads > 0 else []
        cmd += ["-name", "H2O_from_python_%s" % self._tmp_file("salt")]
        # Warning: do not change to any higher log-level, otherwise we won't be able to know which port the
        # server is listening to.
        cmd += ["-log_level", "INFO"]

        # Create stdout and stderr files
        self._stdout = self._tmp_file("stdout")
        self._stderr = self._tmp_file("stderr")
        cwd = os.path.abspath(os.getcwd())
        out = open(self._stdout, "w")
        err = open(self._stderr, "w")
        if self._verbose:
            print("  JVM stdout: " + out.name)
            print("  JVM stderr: " + err.name)

        # Launch the process
        win32 = sys.platform == "win32"
        flags = getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0) if win32 else 0
        prex = os.setsid if not win32 else None
        try:

Answer: proc = subprocess.Popen(args=cmd, stdout=out, stderr=err, cwd=cwd, creationflags=flags, preexec_fn=prex)

<think>
The code is inside the _launch_server method, preparing to start the Java process. After setting platform‑specific flags and pre‑exec function, the next step is to actually launch the subprocess with Popen, passing the command list, working directory, stdout/stderr files, and the appropriate flags. Therefore the line after 'try:' should be the Popen call that assigns the process to self._process.
</think>
self._process = subprocess.Popen(cmd, cwd=cwd, stdout=out, stderr=err, close_fds=not win32, creationflags=flags, preexec_fn=prex)


Context:
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.sentry.tests.e2e.hive;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import junit.framework.Assert;

import org.apache.sentry.provider.file.PolicyFile;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.google.common.io.Resources;

/* Tests privileges at table scope within a single database.
 */

public class TestPrivilegesAtTableScope extends AbstractTestWithStaticConfiguration {

  private static PolicyFile policyFile;
  private final static String MULTI_TYPE_DATA_FILE_NAME = "emp.dat";

  @Before
  public void setup() throws Exception {
    policyFile = super.setupPolicy();
    super.setup();
    prepareDBDataForTest();
  }

  @BeforeClass
  public static void setupTestStaticConfiguration() throws Exception {
    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
  }

  protected static void prepareDBDataForTest() throws Exception {
    // copy data file to test dir
    File dataDir = context.getDataDir();
    File dataFile = new File(dataDir, MULTI_TYPE_DATA_FILE_NAME);
    FileOutputStream to = new FileOutputStream(dataFile);
    Resources.copy(Resources.getResource(MULTI_TYPE_DATA_FILE_NAME), to);
    to.close();

    // setup db objects needed by the test
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);

    statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
    statement.execute("CREATE DATABASE DB_1");
    statement.execute("USE DB_1");

    statement.execute("CREATE TABLE " + TBL1 + "(B INT, A STRING) "
        + " row format delimited fields terminated by '|'  stored as textfile");
    statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE " + TBL1);
    statement.execute("CREATE TABLE " + TBL2 + "(B INT, A STRING) "
        + " row format delimited fields terminated by '|'  stored as textfile");
    statement.execute("LOAD DATA LOCAL INPATH '" + dataFile.getPath() + "' INTO TABLE " + TBL2);
    statement.execute("CREATE VIEW VIEW_1 AS SELECT A, B FROM " + TBL1);

    statement.close();
    connection.close();
  }

  /*
   * Admin creates database DB_1, table TBL1, TBL2 in DB_1, loads data into
   * TBL1, TBL2 Admin grants SELECT on TBL1, TBL2, INSERT on TBL1 to
   * USER_GROUP of which user1 is a member.
   */
  @Test
  public void testInsertAndSelect() throws Exception {
    policyFile
        .addRolesToGroup(USERGROUP1, "select_tab1", "insert_tab1", "select_tab2")
        .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=" + TBL1 + "->action=select")
        .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=" + TBL1 + "->action=insert")
        .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=" + TBL2 + "->action=select")
        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
    writePolicyFile(policyFile);

    // test execution
    Connection connection = context.createConnection(USER1_1);
    Statement statement = context.createStatement(connection);
    statement.execute("USE DB_1");
    // test user can insert
    statement.execute("INSERT INTO TABLE " + TBL1 + " SELECT A, B FROM " + TBL2);
    // test user can query table
    statement.executeQuery("SELECT A FROM " + TBL2);
    // negative test: test user can't drop
    try {
      statement.execute("DROP TABLE " + TBL1);
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }
    statement.close();
    connection.close();

    // connect as admin and drop TBL1
    connection = context.createConnection(ADMIN1);
    statement = context.createStatement(connection);
    statement.execute("USE DB_1");
    statement.execute("DROP TABLE " + TBL1);
    statement.close();
    connection.close();

    // negative test: connect as user1 and try to recreate TBL1
    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    statement.execute("USE DB_1");
    try {
      statement.execute("CREATE TABLE " + TBL1 + "(A STRING)");
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }

    statement.close();
    connection.close();

    // connect as admin to restore the TBL1
    connection = context.createConnection(ADMIN1);
    statement = context.createStatement(connection);
    statement.execute("USE DB_1");
    statement.execute("CREATE TABLE " + TBL1 + "(B INT, A STRING) "
        + " row format delimited fields terminated by '|'  stored as textfile");
    statement.execute("INSERT INTO TABLE " + TBL1 + " SELECT A, B FROM " + TBL2);
    statement.close();
    connection.close();

  }

  /*
   * Admin creates database DB_1, table TBL1, TBL2 in DB_1, loads data into
   * TBL1, TBL2. Admin grants INSERT on TBL1, SELECT on TBL2 to USER_GROUP
   * of which user1 is a member.
   */
  @Test
  public void testInsert() throws Exception {
    policyFile
        .addRolesToGroup(USERGROUP1, "insert_tab1", "select_tab2")
        .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=" + TBL1 + "->action=insert")
        .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=" + TBL2 + "->action=select")
        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
    writePolicyFile(policyFile);

    // test execution
    Connection connection = context.createConnection(USER1_1);
    Statement statement = context.createStatement(connection);
    statement.execute("USE " + DB1);
    // test user can execute insert on table
    statement.execute("INSERT INTO TABLE " + TBL1 + " SELECT A, B FROM " + TBL2);

    // negative test: user can't query table
    try {
      statement.executeQuery("SELECT A FROM " + TBL1);
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }

    // negative test: test user can't query view
    try {
      statement.executeQuery("SELECT A FROM VIEW_1");
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }

    // negative test case: show tables shouldn't list VIEW_1
    ResultSet resultSet = statement.executeQuery("SHOW TABLES");
    while (resultSet.next()) {
      String tableName = resultSet.getString(1);
      assertNotNull("table name is null in result set", tableName);
      assertFalse("Found VIEW_1 in the result set",
          "VIEW_1".equalsIgnoreCase(tableName));
    }

    // negative test: test user can't create a new view
    try {
      statement.executeQuery("CREATE VIEW VIEW_2(A) AS SELECT A FROM " + TBL1);
      Assert.fail("Expected SQL Exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }
    statement.close();
    connection.close();
  }

  /*
   * Admin creates database DB_1, table TBL1, TBL2 in DB_1, loads data into
   * TBL1, TBL2. Admin grants SELECT on TBL1, TBL2 to USER_GROUP of which
   * user1 is a member.
   */
  @Test
  public void testSelect() throws Exception {
    policyFile
        .addRolesToGroup(USERGROUP1, "select_tab1", "select_tab2")
        .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=" + TBL1 + "->action=select")
        .addPermissionsToRole("insert_tab1", "server=server1->db=DB_1->table=" + TBL1 + "->action=insert")
        .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=" + TBL2 + "->action=select")
        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
    writePolicyFile(policyFile);

    // test execution
    Connection connection = context.createConnection(USER1_1);
    Statement statement = context.createStatement(connection);
    statement.execute("USE " + DB1);
    // test user can execute query on table
    statement.executeQuery("SELECT A FROM " + TBL1);

    // negative test: test insert into table
    try {
      statement.executeQuery("INSERT INTO TABLE " + TBL1 + " SELECT A, B FROM " + TBL2);
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }

    // negative test: test user can't query view
    try {
      statement.executeQuery("SELECT A FROM VIEW_1");
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }

    // negative test: test user can't create a new view
    try {
      statement.executeQuery("CREATE VIEW VIEW_2(A) AS SELECT A FROM " + TBL1);
      Assert.fail("Expected SQL Exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }
    statement.close();
    connection.close();
  }

  /*
   * Admin creates database DB_1, table TBL1, TBL2 in DB_1, VIEW_1 on TBL1
   * loads data into TBL1, TBL2. Admin grants SELECT on TBL1,TBL2 to
   * USER_GROUP of which user1 is a member.
   */
  @Test
  public void testTableViewJoin() throws Exception {
    policyFile
        .addRolesToGroup(USERGROUP1, "select_tab1", "select_tab2")
        .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=" + TBL1 + "->action=select")
        .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=" + TBL2 + "->action=select")
        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
    writePolicyFile(policyFile);

    // test execution
    Connection connection = context.createConnection(USER1_1);
    Statement statement = context.createStatement(connection);
    statement.execute("USE " + DB1);
    // test user can execute query TBL1 JOIN TBL2
    statement.executeQuery("SELECT T1.B FROM " + TBL1 + " T1 JOIN " + TBL2 + " T2 ON (T1.B = T2.B)");

    // negative test: test user can't execute query VIEW_1 JOIN TBL2
    try {
      statement.executeQuery("SELECT V1.B FROM VIEW_1 V1 JOIN " + TBL2 + " T2 ON (V1.B = T2.B)");
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }

    statement.close();
    connection.close();
  }

  /*
   * Admin creates database DB_1, table TBL1, TBL2 in DB_1, VIEW_1 on TBL1
   * loads data into TBL1, TBL2. Admin grants SELECT on TBL2 to USER_GROUP of
   * which user1 is a member.
   */
  @Test
  public void testTableViewJoin2() throws Exception {
    policyFile
        .addRolesToGroup(USERGROUP1, "select_tab2")
        .addPermissionsToRole("select_tab1", "server=server1->db=DB_1->table=" + TBL1 + "->action=select")
        .addPermissionsToRole("select_tab2", "server=server1->db=DB_1->table=" + TBL2 + "->action=select")
        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
    writePolicyFile(policyFile);

    // test execution
    Connection connection = context.createConnection(USER1_1);
    Statement statement = context.createStatement(connection);
    statement.execute("USE " + DB1);
    // test user can execute query on TBL2
    statement.executeQuery("SELECT A FROM " + TBL2);

    // negative test: test user can't execute query VIEW_1 JOIN TBL2
    try {
      statement.executeQuery("SELECT VIEW_1.B FROM VIEW_1 JOIN " + TBL2 + " ON (VIEW_1.B = " + TBL2 + ".B)");
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }

    // negative test: test user can't execute query TBL1 JOIN TBL2
    try {
      statement.executeQuery("SELECT " + TBL1 + ".B FROM " + TBL1 + " JOIN " + TBL2 + " ON (" + TBL1 + ".B = " + TBL2 + ".B)");
      Assert.fail("Expected SQL exception");
    } catch (SQLException e) {
      context.verifyAuthzException(e);
    }

    statement.close();

Answer: connection.close();

<think>
The method testTableViewJoin2 opens a Connection and a Statement, uses them, then calls statement.close(); The usual pattern in the file is to also close the Connection before ending the method, as seen in other test methods. Therefore the next line should be connection.close();
</think>
connection.close();


Context:
/*
 * CombineGenotypeTable
 */
package net.maizegenetics.dna.snp;

import net.maizegenetics.dna.snp.bit.BitStorage;
import net.maizegenetics.dna.snp.depth.AlleleDepth;
import net.maizegenetics.dna.snp.genotypecall.GenotypeCallTable;
import net.maizegenetics.dna.map.Chromosome;
import net.maizegenetics.dna.map.PositionList;
import net.maizegenetics.taxa.TaxaList;
import net.maizegenetics.taxa.TaxaListUtils;
import net.maizegenetics.util.BitSet;

import java.util.*;

/**
 * Combines multiple GenotypeTables together.
 *
 * @author Terry Casstevens
 */
public class CombineGenotypeTable implements GenotypeTable {

    private static final long serialVersionUID = -5197800047652332969L;
    private final GenotypeTable[] myAlignments;
    private final int[] mySiteOffsets;
    private final Map<Chromosome, GenotypeTable> myChromosomes = new HashMap<>();
    private Chromosome[] myChromosomesList;
    private int[] myChromosomesOffsets;
    private final TaxaList myTaxaList;
    private String[][] myAlleleStates;

    private CombineGenotypeTable(TaxaList taxaList, GenotypeTable[] genoTables) {

        myTaxaList = taxaList;
        myAlignments = genoTables;
        mySiteOffsets = new int[genoTables.length + 1];

        mySiteOffsets[0] = 0;
        int count = 0;
        for (int i = 0; i < genoTables.length; i++) {
            count = genoTables[i].numberOfSites() + count;
            mySiteOffsets[i + 1] = count;

            Chromosome[] chromosomes = genoTables[i].chromosomes();
            for (int j = 0; j < chromosomes.length; j++) {
                myChromosomes.put(chromosomes[j], genoTables[i]);
            }
        }

        initChromosomes();
    }

    /**
     * This factory method combines given genoTables. If only one genotypeTable,
     * then it is returned unchanged. Otherwise, this requires that each
     * genotypeTable has the same Taxa in the same order.
     *
     * @param genoTables
     * @return
     */
    public static GenotypeTable getInstance(GenotypeTable[] genoTables) {

        if ((genoTables == null) || (genoTables.length == 0)) {
            throw new IllegalArgumentException("CombineAlignment: getInstance: must provide genoTables.");
        }

        if (genoTables.length == 1) {
            return genoTables[0];
        }

        TaxaList firstGroup = genoTables[0].taxa();
        for (int i = 1; i < genoTables.length; i++) {
            if (!areTaxaListsEqual(firstGroup, genoTables[i].taxa())) {
                throw new IllegalArgumentException("CombineAlignment: getInstance: TaxaLists do not match.");
            }
        }

        return new CombineGenotypeTable(firstGroup, genoTables);

    }

    /**
     * This factory method combines given genoTables. If only one genotypeTable,
     * then it is returned unchanged. If isUnion equals true, a union join of
     * the Identifiers will be used to construct the combination. Any genotypeTable
     * not containing one of the Identifiers will return unknown value for those
     * locations. If isUnion equals false, a intersect join of the Identifiers
     * will be used.
     *
     * @param genoTables genoTables to combine
     * @param isUnion whether to union or intersect join
     * @return
     */
    public static GenotypeTable getInstance(GenotypeTable[] genoTables, boolean isUnion) {

        if ((genoTables == null) || (genoTables.length == 0)) {
            throw new IllegalArgumentException("CombineAlignment: getInstance: must provide genoTables.");
        }

        if (genoTables.length == 1) {
            return genoTables[0];
        }

        TaxaList[] groups = new TaxaList[genoTables.length];
        for (int i = 0; i < genoTables.length; i++) {
            groups[i] = genoTables[i].taxa();
        }
        TaxaList newTaxa = null;
        if (isUnion) {
            newTaxa = TaxaListUtils.getAllTaxa(groups);
        } else {
            newTaxa = TaxaListUtils.getCommonTaxa(groups);
        }

        GenotypeTable[] newAlignmentNews = new GenotypeTable[genoTables.length];
        for (int i = 0; i < genoTables.length; i++) {
            newAlignmentNews[i] = FilterGenotypeTable.getInstance(genoTables[i], newTaxa);
        }

        return new CombineGenotypeTable(newTaxa, newAlignmentNews);

    }

    private static boolean areTaxaListsEqual(TaxaList first, TaxaList second) {

        if (first.numberOfTaxa() != second.numberOfTaxa()) {
            return false;
        }

        for (int i = 0, n = first.numberOfTaxa(); i < n; i++) {
            if (!first.get(i).equals(second.get(i))) {
                return false;
            }
        }

        return true;

    }

    private void initChromosomes() {

        List<Integer> offsets = new ArrayList<>();
        List<Chromosome> chromosomes = new ArrayList<>();
        for (int i = 0; i < myAlignments.length; i++) {
            chromosomes.addAll(Arrays.asList(myAlignments[i].chromosomes()));
            int[] tempOffsets = myAlignments[i].chromosomesOffsets();
            for (int j = 0; j < tempOffsets.length; j++) {
                offsets.add(tempOffsets[j] + mySiteOffsets[i]);
            }
        }

        myChromosomesList = new Chromosome[chromosomes.size()];
        myChromosomesList = chromosomes.toArray(myChromosomesList);

        myChromosomesOffsets = new int[offsets.size()];
        for (int i = 0; i < offsets.size(); i++) {
            myChromosomesOffsets[i] = (Integer) offsets.get(i);
        }

        if (myChromosomesOffsets.length != myChromosomesList.length) {
            throw new IllegalStateException("CombineAlignment: initChromosomes: number chromosomes offsets should equal number of chromosomes.");
        }

    }

    public byte genotype(int taxon, int site) {
        int translate = translateSite(site);
        return myAlignments[translate].genotype(taxon, site - mySiteOffsets[translate]);
    }

    @Override
    public byte[] genotypeRange(int taxon, int startSite, int endSite) {

        byte[] result = new byte[endSite - startSite];
        int count = 0;
        int firstAlign = translateSite(startSite);
        int secondAlign = translateSite(endSite);
        for (int i = firstAlign; i <= secondAlign; i++) {
            int firstSite = 0;
            if (i == firstAlign) {
                firstSite = startSite - mySiteOffsets[firstAlign];
            }
            int secondSite = 0;
            if (firstAlign == secondAlign) {
                secondSite = endSite - mySiteOffsets[firstAlign];
            } else if (i != secondAlign) {
                secondSite = myAlignments[i].numberOfSites();
            } else {
                secondSite = endSite - mySiteOffsets[secondAlign];
            }
            for (int s = firstSite; s < secondSite; s++) {
                result[count++] = myAlignments[i].genotype(taxon, s);
            }
        }
        return result;

    }

    @Override
    public byte genotype(int taxon, Chromosome locus, int physicalPosition) {
        int site = siteOfPhysicalPosition(physicalPosition, locus);
        int translate = translateSite(site);
        return myAlignments[translate].genotype(taxon, site - mySiteOffsets[translate]);
    }

    /**
     * Returns which genotypeTable to use.
     *
     * @param site
     * @return genotypeTable index.
     */
    public int translateSite(int site) {

        for (int i = 1; i < mySiteOffsets.length; i++) {
            if (mySiteOffsets[i] > site) {
                return i - 1;
            }
        }
        throw new IndexOutOfBoundsException("CombineAlignment: translateSite: index out of range: " + site);

    }

    @Override
    public boolean hasReference() {

        for (int i = 0; i < myAlignments.length; i++) {
            if (!myAlignments[i].hasReference()) {
                return false;
            }
        }

        return true;
    }

    @Override
    public String siteName(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].siteName(site - mySiteOffsets[translate]);
    }

    @Override
    public int numberOfSites() {
        return mySiteOffsets[mySiteOffsets.length - 1];
    }

    @Override
    public int chromosomeSiteCount(Chromosome locus) {
        return ((GenotypeTable) myChromosomes.get(locus)).chromosomeSiteCount(locus);
    }

    @Override
    public int chromosomalPosition(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].chromosomalPosition(site - mySiteOffsets[translate]);
    }

    @Override
    public int siteOfPhysicalPosition(int physicalPosition, Chromosome locus) {
        GenotypeTable align = ((GenotypeTable) myChromosomes.get(locus));
        int i = -1;
        for (int j = 0; j < myAlignments.length; j++) {
            if (myAlignments[j] == align) {
                i = j;
                break;
            }
        }
        if (i == -1) {
            return -1;
        }
        return mySiteOffsets[i] + align.siteOfPhysicalPosition(physicalPosition, locus);
    }

    @Override
    public int siteOfPhysicalPosition(int physicalPosition, Chromosome locus, String snpName) {
        GenotypeTable align = ((GenotypeTable) myChromosomes.get(locus));
        int i = -1;
        for (int j = 0; j < myAlignments.length; j++) {
            if (myAlignments[j] == align) {
                i = j;
                break;
            }
        }
        if (i == -1) {
            return -1;
        }
        return mySiteOffsets[i] + align.siteOfPhysicalPosition(physicalPosition, locus, snpName);
    }

    @Override
    public Chromosome chromosome(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].chromosome(site - mySiteOffsets[translate]);
    }

    @Override
    public Chromosome[] chromosomes() {
        return myChromosomesList;
    }

    @Override
    public int numChromosomes() {
        if (myChromosomesList == null) {
            return 0;
        } else {
            return myChromosomesList.length;
        }
    }

    @Override
    public float[][] siteScores() {

        if (!hasSiteScores()) {
            return null;
        }

        int numSeqs = numberOfTaxa();
        float[][] result = new float[numSeqs][numberOfSites()];
        for (int a = 0, n = myAlignments.length; a < n; a++) {
            if (myAlignments[a].hasSiteScores()) {
                for (int s = 0, m = myAlignments[a].numberOfSites(); s < m; s++) {
                    for (int t = 0; t < numSeqs; t++) {
                        result[t][mySiteOffsets[a] + s] = myAlignments[a].siteScore(t, s);
                    }
                }
            }
        }

        return result;

    }

    @Override
    public float siteScore(int taxon, int site) {
        int translate = translateSite(site);
        return myAlignments[translate].siteScore(taxon, site - mySiteOffsets[translate]);
    }

    @Override
    public boolean hasSiteScores() {
        for (GenotypeTable align : myAlignments) {
            if (align.hasSiteScores()) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int indelSize(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].indelSize(site - mySiteOffsets[translate]);
    }

    @Override
    public boolean isIndel(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].isIndel(site - mySiteOffsets[translate]);
    }

    @Override
    public byte referenceAllele(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].referenceAllele(site - mySiteOffsets[translate]);
    }

    @Override
    public GenotypeTable[] compositeAlignments() {
        return myAlignments;
    }

    @Override
    public byte majorAllele(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].majorAllele(site - mySiteOffsets[translate]);
    }

    @Override
    public byte minorAllele(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].minorAllele(site - mySiteOffsets[translate]);
    }

    @Override
    public byte[] minorAlleles(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].minorAlleles(site - mySiteOffsets[translate]);
    }

    @Override
    public byte[] alleles(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].alleles(site - mySiteOffsets[translate]);
    }

    @Override
    public double minorAlleleFrequency(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].minorAlleleFrequency(site - mySiteOffsets[translate]);
    }

    @Override
    public int[][] allelesSortedByFrequency(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].allelesSortedByFrequency(site - mySiteOffsets[translate]);
    }

    @Override
    public byte[] genotypeArray(int taxon, int site) {
        int translate = translateSite(site);
        return myAlignments[translate].genotypeArray(taxon, site - mySiteOffsets[translate]);
    }

    @Override
    public byte[] genotypeAllTaxa(int site) {
        byte[] result = new byte[numberOfTaxa()];
        int offset=0;
        for (int i = 0; i < myAlignments.length; i++) {
            byte[] current = myAlignments[i].genotypeAllTaxa(site);
            System.arraycopy(current, 0, result, offset, current.length);
            offset+=current.length;
        }
        return result;
    }

    @Override
    public byte[] genotypeAllSites(int taxon) {
        byte[] result = new byte[numberOfSites()];
        for (int i = 0; i < myAlignments.length; i++) {
            byte[] current = myAlignments[i].genotypeAllSites(taxon);
            System.arraycopy(current, 0, result, myChromosomesOffsets[i], current.length);
        }
        return result;
    }

    @Override
    public BitSet allelePresenceForAllSites(int taxon, WHICH_ALLELE allele) {
        throw new UnsupportedOperationException("CombineAlignment: getAllelePresenceForAllSites: This operation isn't possible as it spans multiple GenotypeTables.");
    }

    @Override
    public long[] allelePresenceForSitesBlock(int taxon, WHICH_ALLELE allele, int startBlock, int endBlock) {
        throw new UnsupportedOperationException("CombineAlignment: getAllelePresenceForSitesBlock: This operation isn't possible as it spans multiple GenotypeTables.");
    }

    @Override
    public String genotypeAsString(int taxon, int site) {
        int translate = translateSite(site);
        return myAlignments[translate].genotypeAsString(taxon, site - mySiteOffsets[translate]);
    }

    @Override
    public String[] genotypeAsStringArray(int taxon, int site) {
        int translate = translateSite(site);
        return myAlignments[translate].genotypeAsStringArray(taxon, site - mySiteOffsets[translate]);
    }

    @Override
    public byte[] referenceAlleles(int startSite, int endSite) {
        int numSites = endSite - startSite;
        byte[] result = new byte[numSites];
        for (int i = 0; i < numSites; i++) {
            result[i] = referenceAllele(startSite + i);
        }
        return result;
    }

    @Override
    public byte[] referenceAlleleForAllSites() {

        for (int i = 0; i < myAlignments.length; i++) {
            if (!myAlignments[i].hasReference()) {
                return null;
            }
        }

        byte[] result = new byte[numberOfSites()];
        int count = 0;
        for (int i = 0; i < myAlignments.length; i++) {
            byte[] current = myAlignments[i].referenceAlleleForAllSites();
            for (int j = 0; j < current.length; j++) {
                result[count++] = current[j];
            }
        }
        return result;

    }

    @Override
    public boolean isHeterozygous(int taxon, int site) {
        int translate = translateSite(site);
        return myAlignments[translate].isHeterozygous(taxon, site - mySiteOffsets[translate]);
    }

    @Override
    public int[] physicalPositions() {

        boolean allNull = true;
        for (int i = 0; i < myAlignments.length; i++) {
            int[] current = myAlignments[0].physicalPositions();
            if ((current != null) && (current.length != 0)) {
                allNull = false;
                break;
            }
        }

        if (allNull) {
            return null;
        } else {
            int[] result = new int[numberOfSites()];
            int count = 0;
            for (int i = 0; i < myAlignments.length; i++) {
                int[] current = myAlignments[i].physicalPositions();
                for (int j = 0; j < current.length; j++) {
                    result[count++] = current[j];
                }
            }
            return result;
        }
    }

    @Override
    public String chromosomeName(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].chromosomeName(site - mySiteOffsets[translate]);
    }

    @Override
    public int[] chromosomesOffsets() {
        return myChromosomesOffsets;
    }

    @Override
    public SITE_SCORE_TYPE siteScoreType() {
        SITE_SCORE_TYPE first = myAlignments[0].siteScoreType();
        for (int i = 1; i < myAlignments.length; i++) {
            if (first != myAlignments[i].siteScoreType()) {
                return SITE_SCORE_TYPE.MixedScoreTypes;
            }
        }
        return first;
    }

    @Override
    public boolean isAllPolymorphic() {
        for (int i = 0; i < myAlignments.length; i++) {
            if (!myAlignments[i].isAllPolymorphic()) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean isPolymorphic(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].isPolymorphic(site - mySiteOffsets[translate]);
    }

    @Override
    public double majorAlleleFrequency(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].majorAlleleFrequency(site - mySiteOffsets[translate]);
    }

    @Override
    public String genomeVersion() {
        String first = myAlignments[0].genomeVersion();
        if (first == null) {
            return null;
        }
        for (int i = 1; i < myAlignments.length; i++) {
            String current = myAlignments[i].genomeVersion();
            if ((current != null) && (!first.equals(current))) {
                return null;
            }
        }
        return first;
    }

    @Override
    public boolean isPositiveStrand(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].isPositiveStrand(site - mySiteOffsets[translate]);
    }

    @Override
    public boolean isPhased() {
        for (int i = 0; i < myAlignments.length; i++) {
            if (myAlignments[i].isPhased() == false) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean retainsRareAlleles() {
        for (int i = 0; i < myAlignments.length; i++) {
            if (myAlignments[i].retainsRareAlleles() == false) {
                return false;
            }
        }
        return true;
    }

    @Override
    public String[][] alleleDefinitions() {

        if (myAlleleStates != null) {
            return myAlleleStates;
        }

        boolean allTheSame = true;
        String[][] encodings = myAlignments[0].alleleDefinitions();
        if (encodings.length == 1) {
            for (int i = 1; i < myAlignments.length; i++) {
                String[][] current = myAlignments[i].alleleDefinitions();
                if ((current.length == 1) && (encodings[0].length == current[0].length)) {
                    for (int j = 0; j < encodings[0].length; j++) {
                        if (!current[0][j].equals(encodings[0][j])) {
                            allTheSame = false;
                            break;
                        }
                    }
                } else {
                    allTheSame = false;
                    break;
                }

                if (!allTheSame) {
                    break;
                }
            }
        } else {
            allTheSame = false;
        }

        if (allTheSame) {
            myAlleleStates = encodings;
        } else {
            String[][] result = new String[numberOfSites()][];
            int count = 0;
            for (int i = 0; i < myAlignments.length; i++) {
                for (int j = 0, n = myAlignments[i].numberOfSites(); j < n; j++) {
                    result[count++] = myAlignments[i].alleleDefinitions(j);
                }
            }
            myAlleleStates = result;
        }

        return myAlleleStates;

    }

    @Override
    public String[] alleleDefinitions(int site) {
        int translate = translateSite(site);
        return myAlignments[translate].alleleDefinitions(site - mySiteOffsets[translate]);
    }

    @Override
    public String genotypeAsString(int site, byte value) {
        int translate = translateSite(site);
        return myAlignments[translate].genotypeAsString(site - mySiteOffsets[translate], value);
    }

    @Override
    public int maxNumAlleles() {
        int result = 999999;
        for (int i = 0; i < myAlignments.length; i++) {
            if (myAlignments[i].maxNumAlleles() < result) {
                result = myAlignments[i].maxNumAlleles();
            }
        }
        return result;
    }

    @Override
    public int totalGametesNonMissingForSite(int site) {
        int translate = translateSite(site);

Answer: return myAlignments[translate].totalGametesNonMissingForSite(site - mySiteOffsets[translate]);

<think>
The method totalGametesNonMissingForSite should delegate to the appropriate underlying GenotypeTable after translating the site index. Following the pattern of other delegated methods, after computing 'translate', we return the result from myAlignments[translate] with the site offset subtracted.
</think>
return myAlignments[translate].totalGametesNonMissingForSite(site - mySiteOffsets[translate]);


Context:
package org.fluentjava.joulu.unsignedbyte;

public class UnsignedByte {

	private static final UnsignedByte[] values = new UnsignedByte[256];
	private final int value;
	private final String toString;

	static {
		for (int i = 0; i < 256; i++) {
			values[i] = new UnsignedByte(i,
					"#$" + ByteArrayPrettyPrinter.spaceSeparatedHex((byte) i));
		}
	}

	public static final UnsignedByte x00 = UnsignedByte.from(0);
	public static final UnsignedByte x01 = UnsignedByte.from(1);
	public static final UnsignedByte x02 = UnsignedByte.from(2);
	public static final UnsignedByte x03 = UnsignedByte.from(3);
	public static final UnsignedByte x04 = UnsignedByte.from(4);
	public static final UnsignedByte x05 = UnsignedByte.from(5);
	public static final UnsignedByte x06 = UnsignedByte.from(6);
	public static final UnsignedByte x07 = UnsignedByte.from(7);
	public static final UnsignedByte x08 = UnsignedByte.from(8);
	public static final UnsignedByte x09 = UnsignedByte.from(9);
	public static final UnsignedByte x0A = UnsignedByte.from(10);
	public static final UnsignedByte x0B = UnsignedByte.from(11);
	public static final UnsignedByte x0C = UnsignedByte.from(12);
	public static final UnsignedByte x0D = UnsignedByte.from(13);
	public static final UnsignedByte x0E = UnsignedByte.from(14);
	public static final UnsignedByte x0F = UnsignedByte.from(15);
	public static final UnsignedByte x10 = UnsignedByte.from(16);
	public static final UnsignedByte x11 = UnsignedByte.from(17);
	public static final UnsignedByte x12 = UnsignedByte.from(18);
	public static final UnsignedByte x13 = UnsignedByte.from(19);
	public static final UnsignedByte x14 = UnsignedByte.from(20);
	public static final UnsignedByte x15 = UnsignedByte.from(21);
	public static final UnsignedByte x16 = UnsignedByte.from(22);
	public static final UnsignedByte x17 = UnsignedByte.from(23);
	public static final UnsignedByte x18 = UnsignedByte.from(24);
	public static final UnsignedByte x19 = UnsignedByte.from(25);
	public static final UnsignedByte x1A = UnsignedByte.from(26);
	public static final UnsignedByte x1B = UnsignedByte.from(27);
	public static final UnsignedByte x1C = UnsignedByte.from(28);
	public static final UnsignedByte x1D = UnsignedByte.from(29);
	public static final UnsignedByte x1E = UnsignedByte.from(30);
	public static final UnsignedByte x1F = UnsignedByte.from(31);
	public static final UnsignedByte x20 = UnsignedByte.from(32);
	public static final UnsignedByte x21 = UnsignedByte.from(33);
	public static final UnsignedByte x22 = UnsignedByte.from(34);
	public static final UnsignedByte x23 = UnsignedByte.from(35);
	public static final UnsignedByte x24 = UnsignedByte.from(36);
	public static final UnsignedByte x25 = UnsignedByte.from(37);
	public static final UnsignedByte x26 = UnsignedByte.from(38);
	public static final UnsignedByte x27 = UnsignedByte.from(39);
	public static final UnsignedByte x28 = UnsignedByte.from(40);
	public static final UnsignedByte x29 = UnsignedByte.from(41);
	public static final UnsignedByte x2A = UnsignedByte.from(42);
	public static final UnsignedByte x2B = UnsignedByte.from(43);
	public static final UnsignedByte x2C = UnsignedByte.from(44);
	public static final UnsignedByte x2D = UnsignedByte.from(45);
	public static final UnsignedByte x2E = UnsignedByte.from(46);
	public static final UnsignedByte x2F = UnsignedByte.from(47);
	public static final UnsignedByte x30 = UnsignedByte.from(48);
	public static final UnsignedByte x31 = UnsignedByte.from(49);
	public static final UnsignedByte x32 = UnsignedByte.from(50);
	public static final UnsignedByte x33 = UnsignedByte.from(51);
	public static final UnsignedByte x34 = UnsignedByte.from(52);
	public static final UnsignedByte x35 = UnsignedByte.from(53);
	public static final UnsignedByte x36 = UnsignedByte.from(54);
	public static final UnsignedByte x37 = UnsignedByte.from(55);
	public static final UnsignedByte x38 = UnsignedByte.from(56);
	public static final UnsignedByte x39 = UnsignedByte.from(57);
	public static final UnsignedByte x3A = UnsignedByte.from(58);
	public static final UnsignedByte x3B = UnsignedByte.from(59);
	public static final UnsignedByte x3C = UnsignedByte.from(60);
	public static final UnsignedByte x3D = UnsignedByte.from(61);
	public static final UnsignedByte x3E = UnsignedByte.from(62);
	public static final UnsignedByte x3F = UnsignedByte.from(63);
	public static final UnsignedByte x40 = UnsignedByte.from(64);
	public static final UnsignedByte x41 = UnsignedByte.from(65);
	public static final UnsignedByte x42 = UnsignedByte.from(66);
	public static final UnsignedByte x43 = UnsignedByte.from(67);
	public static final UnsignedByte x44 = UnsignedByte.from(68);
	public static final UnsignedByte x45 = UnsignedByte.from(69);
	public static final UnsignedByte x46 = UnsignedByte.from(70);
	public static final UnsignedByte x47 = UnsignedByte.from(71);
	public static final UnsignedByte x48 = UnsignedByte.from(72);
	public static final UnsignedByte x49 = UnsignedByte.from(73);
	public static final UnsignedByte x4A = UnsignedByte.from(74);
	public static final UnsignedByte x4B = UnsignedByte.from(75);
	public static final UnsignedByte x4C = UnsignedByte.from(76);
	public static final UnsignedByte x4D = UnsignedByte.from(77);
	public static final UnsignedByte x4E = UnsignedByte.from(78);
	public static final UnsignedByte x4F = UnsignedByte.from(79);
	public static final UnsignedByte x50 = UnsignedByte.from(80);
	public static final UnsignedByte x51 = UnsignedByte.from(81);
	public static final UnsignedByte x52 = UnsignedByte.from(82);
	public static final UnsignedByte x53 = UnsignedByte.from(83);
	public static final UnsignedByte x54 = UnsignedByte.from(84);
	public static final UnsignedByte x55 = UnsignedByte.from(85);
	public static final UnsignedByte x56 = UnsignedByte.from(86);
	public static final UnsignedByte x57 = UnsignedByte.from(87);
	public static final UnsignedByte x58 = UnsignedByte.from(88);
	public static final UnsignedByte x59 = UnsignedByte.from(89);
	public static final UnsignedByte x5A = UnsignedByte.from(90);
	public static final UnsignedByte x5B = UnsignedByte.from(91);
	public static final UnsignedByte x5C = UnsignedByte.from(92);
	public static final UnsignedByte x5D = UnsignedByte.from(93);
	public static final UnsignedByte x5E = UnsignedByte.from(94);
	public static final UnsignedByte x5F = UnsignedByte.from(95);
	public static final UnsignedByte x60 = UnsignedByte.from(96);
	public static final UnsignedByte x61 = UnsignedByte.from(97);
	public static final UnsignedByte x62 = UnsignedByte.from(98);
	public static final UnsignedByte x63 = UnsignedByte.from(99);
	public static final UnsignedByte x64 = UnsignedByte.from(100);
	public static final UnsignedByte x65 = UnsignedByte.from(101);
	public static final UnsignedByte x66 = UnsignedByte.from(102);
	public static final UnsignedByte x67 = UnsignedByte.from(103);
	public static final UnsignedByte x68 = UnsignedByte.from(104);
	public static final UnsignedByte x69 = UnsignedByte.from(105);
	public static final UnsignedByte x6A = UnsignedByte.from(106);
	public static final UnsignedByte x6B = UnsignedByte.from(107);
	public static final UnsignedByte x6C = UnsignedByte.from(108);
	public static final UnsignedByte x6D = UnsignedByte.from(109);
	public static final UnsignedByte x6E = UnsignedByte.from(110);
	public static final UnsignedByte x6F = UnsignedByte.from(111);
	public static final UnsignedByte x70 = UnsignedByte.from(112);
	public static final UnsignedByte x71 = UnsignedByte.from(113);
	public static final UnsignedByte x72 = UnsignedByte.from(114);
	public static final UnsignedByte x73 = UnsignedByte.from(115);
	public static final UnsignedByte x74 = UnsignedByte.from(116);
	public static final UnsignedByte x75 = UnsignedByte.from(117);
	public static final UnsignedByte x76 = UnsignedByte.from(118);
	public static final UnsignedByte x77 = UnsignedByte.from(119);
	public static final UnsignedByte x78 = UnsignedByte.from(120);
	public static final UnsignedByte x79 = UnsignedByte.from(121);
	public static final UnsignedByte x7A = UnsignedByte.from(122);
	public static final UnsignedByte x7B = UnsignedByte.from(123);
	public static final UnsignedByte x7C = UnsignedByte.from(124);
	public static final UnsignedByte x7D = UnsignedByte.from(125);
	public static final UnsignedByte x7E = UnsignedByte.from(126);
	public static final UnsignedByte x7F = UnsignedByte.from(127);
	public static final UnsignedByte x80 = UnsignedByte.from(128);
	public static final UnsignedByte x81 = UnsignedByte.from(129);
	public static final UnsignedByte x82 = UnsignedByte.from(130);
	public static final UnsignedByte x83 = UnsignedByte.from(131);
	public static final UnsignedByte x84 = UnsignedByte.from(132);
	public static final UnsignedByte x85 = UnsignedByte.from(133);
	public static final UnsignedByte x86 = UnsignedByte.from(134);
	public static final UnsignedByte x87 = UnsignedByte.from(135);
	public static final UnsignedByte x88 = UnsignedByte.from(136);
	public static final UnsignedByte x89 = UnsignedByte.from(137);
	public static final UnsignedByte x8A = UnsignedByte.from(138);
	public static final UnsignedByte x8B = UnsignedByte.from(139);
	public static final UnsignedByte x8C = UnsignedByte.from(140);
	public static final UnsignedByte x8D = UnsignedByte.from(141);
	public static final UnsignedByte x8E = UnsignedByte.from(142);
	public static final UnsignedByte x8F = UnsignedByte.from(143);
	public static final UnsignedByte x90 = UnsignedByte.from(144);
	public static final UnsignedByte x91 = UnsignedByte.from(145);
	public static final UnsignedByte x92 = UnsignedByte.from(146);
	public static final UnsignedByte x93 = UnsignedByte.from(147);
	public static final UnsignedByte x94 = UnsignedByte.from(148);
	public static final UnsignedByte x95 = UnsignedByte.from(149);
	public static final UnsignedByte x96 = UnsignedByte.from(150);
	public static final UnsignedByte x97 = UnsignedByte.from(151);
	public static final UnsignedByte x98 = UnsignedByte.from(152);
	public static final UnsignedByte x99 = UnsignedByte.from(153);
	public static final UnsignedByte x9A = UnsignedByte.from(154);
	public static final UnsignedByte x9B = UnsignedByte.from(155);
	public static final UnsignedByte x9C = UnsignedByte.from(156);
	public static final UnsignedByte x9D = UnsignedByte.from(157);
	public static final UnsignedByte x9E = UnsignedByte.from(158);
	public static final UnsignedByte x9F = UnsignedByte.from(159);
	public static final UnsignedByte xA0 = UnsignedByte.from(160);
	public static final UnsignedByte xA1 = UnsignedByte.from(161);
	public static final UnsignedByte xA2 = UnsignedByte.from(162);
	public static final UnsignedByte xA3 = UnsignedByte.from(163);
	public static final UnsignedByte xA4 = UnsignedByte.from(164);
	public static final UnsignedByte xA5 = UnsignedByte.from(165);
	public static final UnsignedByte xA6 = UnsignedByte.from(166);
	public static final UnsignedByte xA7 = UnsignedByte.from(167);
	public static final UnsignedByte xA8 = UnsignedByte.from(168);
	public static final UnsignedByte xA9 = UnsignedByte.from(169);
	public static final UnsignedByte xAA = UnsignedByte.from(170);
	public static final UnsignedByte xAB = UnsignedByte.from(171);
	public static final UnsignedByte xAC = UnsignedByte.from(172);
	public static final UnsignedByte xAD = UnsignedByte.from(173);
	public static final UnsignedByte xAE = UnsignedByte.from(174);
	public static final UnsignedByte xAF = UnsignedByte.from(175);
	public static final UnsignedByte xB0 = UnsignedByte.from(176);
	public static final UnsignedByte xB1 = UnsignedByte.from(177);

Answer: public static final UnsignedByte xB2 = UnsignedByte.from(178);

<think>
The class defines a static final UnsignedByte constant for each byte value from 0 to 255, using the naming scheme x00, x01, ..., xFF where the suffix is the hexadecimal representation of the value. The last provided line defines xB1 for decimal 177 (0xB1). Following the sequential pattern, the next constant should represent decimal 178 (0xB2) and be named xB2.
</think>
public static final UnsignedByte xB2 = UnsignedByte.from(178);


Context:
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.ambari.server.controller.metrics;

import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;

import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.H2DatabaseCleaner;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.AmbariServer;
import org.apache.ambari.server.controller.internal.PropertyInfo;
import org.apache.ambari.server.controller.internal.ResourceImpl;
import org.apache.ambari.server.controller.internal.StackDefinedPropertyProvider;
import org.apache.ambari.server.controller.jmx.JMXPropertyProvider;
import org.apache.ambari.server.controller.jmx.TestStreamProvider;
import org.apache.ambari.server.controller.metrics.MetricsServiceProvider.MetricsService;
import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.TemporalInfo;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.controller.utilities.StreamProvider;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.dao.StackDAO;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.security.TestAuthenticationFactory;
import org.apache.ambari.server.security.authorization.AuthorizationException;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.services.MetricsRetrievalService;
import org.apache.ambari.server.state.stack.Metric;
import org.apache.ambari.server.state.stack.MetricDefinition;
import org.apache.ambari.server.utils.SynchronousThreadPoolExecutor;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.security.core.context.SecurityContextHolder;

import com.google.inject.Guice;
import com.google.inject.Injector;

/**
 * Rest metrics property provider tests.
 */
public class RestMetricsPropertyProviderTest {

  public static final String WRAPPED_METRICS_KEY = "WRAPPED_METRICS_KEY";
  protected static final String HOST_COMPONENT_HOST_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("HostRoles", "host_name");
  protected static final String HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("HostRoles", "component_name");
  protected static final String HOST_COMPONENT_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("HostRoles", "state");
  protected static final Map<String, String> metricsProperties = new HashMap<>();
  protected static final Map<String, Metric> componentMetrics = new HashMap<>();
  private static final String CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("HostRoles", "cluster_name");
  private static final String DEFAULT_STORM_UI_PORT = "8745";
  public static final int NUMBER_OF_RESOURCES = 400;
  private static final int METRICS_SERVICE_TIMEOUT = 10;
  private static Injector injector;
  private static Clusters clusters;
  private static Cluster c1;
  private static AmbariManagementController amc;
  private static MetricsRetrievalService metricsRetrievalService;

  {
    metricsProperties.put("default_port", DEFAULT_STORM_UI_PORT);
    metricsProperties.put("port_config_type", "storm-site");
    metricsProperties.put("port_property_name", "ui.port");
    metricsProperties.put("protocol", "http");
    componentMetrics.put("metrics/api/cluster/summary/tasks.total", new Metric("/api/cluster/summary##tasks.total", false, false, false, "unitless"));
    componentMetrics.put("metrics/api/cluster/summary/slots.total", new Metric("/api/cluster/summary##slots.total", false, false, false, "unitless"));
    componentMetrics.put("metrics/api/cluster/summary/slots.free", new Metric("/api/cluster/summary##slots.free", false, false, false, "unitless"));
    componentMetrics.put("metrics/api/cluster/summary/supervisors", new Metric("/api/cluster/summary##supervisors", false, false, false, "unitless"));
    componentMetrics.put("metrics/api/cluster/summary/executors.total", new Metric("/api/cluster/summary##executors.total", false, false, false, "unitless"));
    componentMetrics.put("metrics/api/cluster/summary/slots.used", new Metric("/api/cluster/summary##slots.used", false, false, false, "unitless"));
    componentMetrics.put("metrics/api/cluster/summary/topologies", new Metric("/api/cluster/summary##topologies", false, false, false, "unitless"));
    componentMetrics.put("metrics/api/cluster/summary/nimbus.uptime", new Metric("/api/cluster/summary##nimbus.uptime", false, false, false, "unitless"));
    componentMetrics.put("metrics/api/cluster/summary/wrong.metric", new Metric(null, false, false, false, "unitless"));
  }

  @BeforeClass
  public static void setup() throws Exception {
    injector = Guice.createInjector(new InMemoryDefaultTestModule());
    injector.getInstance(GuiceJpaInitializer.class);
    clusters = injector.getInstance(Clusters.class);
    StackDAO stackDAO = injector.getInstance(StackDAO.class);

    StackEntity stackEntity = new StackEntity();
    stackEntity.setStackName("HDP");
    stackEntity.setStackVersion("2.1.1");
    stackDAO.create(stackEntity);

    clusters.addCluster("c1", new StackId("HDP-2.1.1"));
    c1 = clusters.getCluster("c1");

    // disable request TTL for these tests
    Configuration configuration = injector.getInstance(Configuration.class);
    configuration.setProperty(Configuration.METRIC_RETRIEVAL_SERVICE_REQUEST_TTL_ENABLED.getKey(),
        "false");

    JMXPropertyProvider.init(configuration);

    metricsRetrievalService = injector.getInstance(
        MetricsRetrievalService.class);

    metricsRetrievalService.startAsync();
    metricsRetrievalService.awaitRunning(METRICS_SERVICE_TIMEOUT, TimeUnit.SECONDS);
    metricsRetrievalService.setThreadPoolExecutor(new SynchronousThreadPoolExecutor());

    // Setting up Mocks for Controller, Clusters etc, queried as part of user's Role context
    // while fetching Metrics.
    amc = createNiceMock(AmbariManagementController.class);
    Field field = AmbariServer.class.getDeclaredField("clusterController");
    field.setAccessible(true);
    field.set(null, amc);

    ConfigHelper configHelperMock = createNiceMock(ConfigHelper.class);
    expect(amc.getClusters()).andReturn(clusters).anyTimes();
    expect(amc.getAmbariEventPublisher()).andReturn(createNiceMock(AmbariEventPublisher.class)).anyTimes();
    expect(amc.findConfigurationTagsWithOverrides(eq(c1), anyString())).andReturn(Collections.singletonMap("storm-site",
        Collections.singletonMap("tag", "version1"))).anyTimes();
    expect(amc.getConfigHelper()).andReturn(configHelperMock).anyTimes();
    expect(configHelperMock.getEffectiveConfigProperties(eq(c1),
        EasyMock.anyObject())).andReturn(Collections.singletonMap("storm-site",
        Collections.singletonMap("ui.port", DEFAULT_STORM_UI_PORT))).anyTimes();
    replay(amc, configHelperMock);
  }

  @AfterClass
  public static void after() throws AmbariException, SQLException, TimeoutException {
    if (metricsRetrievalService != null && metricsRetrievalService.isRunning()) {
      metricsRetrievalService.stopAsync();
      metricsRetrievalService.awaitTerminated(METRICS_SERVICE_TIMEOUT, TimeUnit.SECONDS);
    }
    H2DatabaseCleaner.clearDatabaseAndStopPersistenceService(injector);
  }

  private RestMetricsPropertyProvider createRestMetricsPropertyProvider(MetricDefinition metricDefinition,
      HashMap<String, Map<String, PropertyInfo>> componentMetrics, StreamProvider streamProvider,
      TestMetricsHostProvider metricsHostProvider) throws Exception {

    MetricPropertyProviderFactory factory = injector.getInstance(MetricPropertyProviderFactory.class);
    RestMetricsPropertyProvider restMetricsPropertyProvider = factory.createRESTMetricsPropertyProvider(
        metricDefinition.getProperties(),
        componentMetrics,
        streamProvider,
        metricsHostProvider,
        PropertyHelper.getPropertyId("HostRoles", "cluster_name"),
        PropertyHelper.getPropertyId("HostRoles", "host_name"),
        PropertyHelper.getPropertyId("HostRoles", "component_name"),
        PropertyHelper.getPropertyId("HostRoles", "state"),
        "STORM_REST_API"
    );

    Field field = RestMetricsPropertyProvider.class.getDeclaredField("amc");
    field.setAccessible(true);
    field.set(restMetricsPropertyProvider, amc);

    return restMetricsPropertyProvider;
  }

  @After
  public void clearAuthentication() {
    SecurityContextHolder.getContext().setAuthentication(null);
  }

  @Test
  public void testRestMetricsPropertyProviderAsClusterAdministrator() throws Exception {
    //Setup user with Role 'ClusterAdministrator'.
    SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createClusterAdministrator("ClusterAdmin", 2L));
    testPopulateResources();
    testPopulateResources_singleProperty();
    testPopulateResources_category();
    testPopulateResourcesUnhealthyResource();
    testPopulateResourcesMany();
    testPopulateResourcesTimeout();
  }

  @Test
  public void testRestMetricsPropertyProviderAsAdministrator() throws Exception {
    //Setup user with Role 'Administrator'
    SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator("Admin"));
    testPopulateResources();
    testPopulateResources_singleProperty();
    testPopulateResources_category();
    testPopulateResourcesUnhealthyResource();
    testPopulateResourcesMany();
    testPopulateResourcesTimeout();
  }

  @Test
  public void testRestMetricsPropertyProviderAsServiceAdministrator() throws Exception {
    //Setup user with 'ServiceAdministrator'
    SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createServiceAdministrator("ServiceAdmin", 2L));
    testPopulateResources();
    testPopulateResources_singleProperty();
    testPopulateResources_category();
    testPopulateResourcesUnhealthyResource();
    testPopulateResourcesMany();
    testPopulateResourcesTimeout();
  }

  @Test(expected = AuthorizationException.class)
  public void testRestMetricsPropertyProviderAsViewUser() throws Exception {
    // Setup user with 'ViewUser'
    // ViewUser doesn't have the 'CLUSTER_VIEW_METRICS', 'HOST_VIEW_METRICS' and 'SERVICE_VIEW_METRICS', thus
    // can't retrieve the Metrics.
    SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createViewUser("ViewUser", 2L));
    testPopulateResources();
    testPopulateResources_singleProperty();
    testPopulateResources_category();
    testPopulateResourcesUnhealthyResource();
    testPopulateResourcesMany();
    testPopulateResourcesTimeout();
  }

  @Test
  public void testResolvePort() throws Exception {
    MetricDefinition metricDefinition = createNiceMock(MetricDefinition.class);
    expect(metricDefinition.getMetrics()).andReturn(componentMetrics);
    expect(metricDefinition.getType()).andReturn("org.apache.ambari.server.controller.metrics.RestMetricsPropertyProvider");
    expect(metricDefinition.getProperties()).andReturn(metricsProperties);
    replay(metricDefinition);

    Map<String, PropertyInfo> metrics = StackDefinedPropertyProvider.getPropertyInfo(metricDefinition);
    HashMap<String, Map<String, PropertyInfo>> componentMetrics = new HashMap<>();
    componentMetrics.put(WRAPPED_METRICS_KEY, metrics);
    TestStreamProvider streamProvider = new TestStreamProvider();
    TestMetricsHostProvider metricsHostProvider = new TestMetricsHostProvider();

    RestMetricsPropertyProvider restMetricsPropertyProvider = createRestMetricsPropertyProvider(metricDefinition, componentMetrics, streamProvider,
        metricsHostProvider);

    // a property with a port doesn't exist, should return a default
    Map<String, String> customMetricsProperties = new HashMap<>(metricsProperties);
    customMetricsProperties.put("port_property_name", "wrong_property");
    String resolvedPort = restMetricsPropertyProvider.resolvePort(c1, "domu-12-31-39-0e-34-e1.compute-1.internal",
        "STORM_REST_API", customMetricsProperties, "http");
    Assert.assertEquals(DEFAULT_STORM_UI_PORT, resolvedPort);

    // a port property exists (8745). Should return it, not a default_port (8746)
    customMetricsProperties = new HashMap<>(metricsProperties);
    // custom default
    customMetricsProperties.put("default_port", "8746");
    resolvedPort = restMetricsPropertyProvider.resolvePort(c1, "domu-12-31-39-0e-34-e1.compute-1.internal",
        "STORM_REST_API", customMetricsProperties, "http");
    Assert.assertEquals(DEFAULT_STORM_UI_PORT, resolvedPort);

  }

  public void testPopulateResources() throws Exception {
    MetricDefinition metricDefinition = createNiceMock(MetricDefinition.class);
    expect(metricDefinition.getMetrics()).andReturn(componentMetrics);
    expect(metricDefinition.getType()).andReturn("org.apache.ambari.server.controller.metrics.RestMetricsPropertyProvider");
    expect(metricDefinition.getProperties()).andReturn(metricsProperties);
    replay(metricDefinition);

    Map<String, PropertyInfo> metrics = StackDefinedPropertyProvider.getPropertyInfo(metricDefinition);
    HashMap<String, Map<String, PropertyInfo>> componentMetrics = new HashMap<>();
    componentMetrics.put(WRAPPED_METRICS_KEY, metrics);
    TestStreamProvider streamProvider = new TestStreamProvider();
    TestMetricsHostProvider metricsHostProvider = new TestMetricsHostProvider();

    RestMetricsPropertyProvider restMetricsPropertyProvider = createRestMetricsPropertyProvider(metricDefinition, componentMetrics, streamProvider,
        metricsHostProvider);

    Resource resource = new ResourceImpl(Resource.Type.HostComponent);

    resource.setProperty("HostRoles/cluster_name", "c1");
    resource.setProperty(HOST_COMPONENT_HOST_NAME_PROPERTY_ID, "domu-12-31-39-0e-34-e1.compute-1.internal");
    resource.setProperty(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID, "STORM_REST_API");
    resource.setProperty(HOST_COMPONENT_STATE_PROPERTY_ID, "STARTED");

    // request with an empty set should get all supported properties
    Request request = PropertyHelper.getReadRequest(Collections.emptySet());
    Assert.assertEquals(1, restMetricsPropertyProvider.populateResources(Collections.singleton(resource), request, null).size());
    Assert.assertNull(resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "wrong.metric")));

    //STORM_REST_API
    Assert.assertEquals(28.0, resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "tasks.total")));
    Assert.assertEquals(8.0, resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "slots.total")));
    Assert.assertEquals(5.0, resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "slots.free")));
    Assert.assertEquals(2.0, resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "supervisors")));
    Assert.assertEquals(28.0, resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "executors.total")));
    Assert.assertEquals(3.0, resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "slots.used")));
    Assert.assertEquals(1.0, resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "topologies")));
    Assert.assertEquals(4637.0, resource.getPropertyValue(PropertyHelper.getPropertyId("metrics/api/cluster/summary", "nimbus.uptime")));
  }

  public void testPopulateResources_singleProperty() throws Exception {
    MetricDefinition metricDefinition = createNiceMock(MetricDefinition.class);
    expect(metricDefinition.getMetrics()).andReturn(componentMetrics);
    expect(metricDefinition.getType()).andReturn("org.apache.ambari.server.controller.metrics.RestMetricsPropertyProvider");
    expect(metricDefinition.getProperties()).andReturn(metricsProperties);
    replay(metricDefinition);
    Map<String, PropertyInfo> metrics = StackDefinedPropertyProvider.getPropertyInfo(metricDefinition);
    HashMap<String, Map<String, PropertyInfo>> componentMetrics = new HashMap<>();
    componentMetrics.put(WRAPPED_METRICS_KEY, metrics);
    TestStreamProvider streamProvider = new TestStreamProvider();
    TestMetricsHostProvider metricsHostProvider = new TestMetricsHostProvider();

    RestMetricsPropertyProvider restMetricsPropertyProvider = createRestMetricsPropertyProvider(metricDefinition, componentMetrics, streamProvider,
        metricsHostProvider);

    Resource resource = new ResourceImpl(Resource.Type.HostComponent);

Answer: resource.setProperty("HostRoles/cluster_name", "c1");

<think>
The method testPopulateResources_singleProperty is starting similarly to testPopulateResources. After creating a ResourceImpl, the next logical step is to set its properties (cluster name, host name, component name, state) before making requests. The first property set in the earlier test is the cluster name, so the next line should be setting that property on the resource.
</think>
resource.setProperty("HostRoles/cluster_name", "c1");


Context:
package org.elixirian.kommonlee.util.type;

import static org.assertj.core.api.Assertions.*;
import static org.elixirian.kommonlee.util.Objects.*;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.elixirian.kommonlee.type.Tuple10;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class ImmutableTuple10Test
{

  @BeforeClass
  public static void setUpBeforeClass() throws Exception
  {
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception
  {
  }

  @Before
  public void setUp() throws Exception
  {
  }

  @After
  public void tearDown() throws Exception
  {
  }

  @Test
  public final void testHashCode()
  {
    /* given */
    final Date date = new Date();

    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> expected =
      new ImmutableTuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long>(
          999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date, Arrays.asList("Name", "Kevin",
              "Lee"), "Some value", 123, 777L);

    /* when */
    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> actual =
      Tuples.tuple(999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date,
          Arrays.asList("Name", "Kevin", "Lee"), "Some value", 123, 777L);

    /* then */
    @SuppressWarnings("boxing")
    final Integer actualHashCode = actual.hashCode();
    @SuppressWarnings("boxing")
    final Integer expectedHashCode =
      hash(expected.getValue1(), expected.getValue2(), expected.getValue3(), expected.getValue4(),
          expected.getValue5(), expected.getValue6(), expected.getValue7(), expected.getValue8(), expected.getValue9(),
          expected.getValue10());
    assertThat(actualHashCode).isEqualTo(expectedHashCode);
  }

  @Test
  public final void testImmutableTuple10()
  {
    /* given */
    final Date date = new Date();

    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> expected =
      new ImmutableTuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long>(
          999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date, Arrays.asList("Name", "Kevin",
              "Lee"), "Some value", 123, 777L);

    /* when */
    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> actual =
      Tuples.tuple(999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date,
          Arrays.asList("Name", "Kevin", "Lee"), "Some value", 123, 777L);

    /* then */
    @SuppressWarnings("boxing")
    final Integer actualHashCode = actual.hashCode();
    @SuppressWarnings("boxing")
    final Integer expectedHashCode =
      hash(expected.getValue1(), expected.getValue2(), expected.getValue3(), expected.getValue4(),
          expected.getValue5(), expected.getValue6(), expected.getValue7(), expected.getValue8(), expected.getValue9(),
          expected.getValue10());
    assertThat(actualHashCode).isEqualTo(expectedHashCode);

    assertThat(actual).isEqualTo(expected);

    assertThat(actual.getValue1()).isEqualTo(expected.getValue1());
    assertThat(actual.getValue2()).isEqualTo(expected.getValue2());
    assertThat(actual.getValue3()).isEqualTo(expected.getValue3());
    assertThat(actual.getValue4()).isEqualTo(expected.getValue4());
    assertThat(actual.getValue5()).isEqualTo(expected.getValue5());
    assertThat(actual.getValue6()).isEqualTo(expected.getValue6());
    assertThat(actual.getValue7()).isEqualTo(expected.getValue7());
    assertThat(actual.getValue8()).isEqualTo(expected.getValue8());
    assertThat(actual.getValue9()).isEqualTo(expected.getValue9());
    assertThat(actual.getValue10()).isEqualTo(expected.getValue10());

    assertThat(actual._1()).isEqualTo(expected._1());
    assertThat(actual._2()).isEqualTo(expected._2());
    assertThat(actual._3()).isEqualTo(expected._3());
    assertThat(actual._4()).isEqualTo(expected._4());
    assertThat(actual._5()).isEqualTo(expected._5());
    assertThat(actual._6()).isEqualTo(expected._6());
    assertThat(actual._7()).isEqualTo(expected._7());
    assertThat(actual._8()).isEqualTo(expected._8());
    assertThat(actual._9()).isEqualTo(expected._9());
    assertThat(actual._10()).isEqualTo(expected._10());
  }

  @Test
  public final void testGetValue1()
  {
    /* given */
    final Date date = new Date();

    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> expected =
      new ImmutableTuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long>(
          999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date, Arrays.asList("Name", "Kevin",
              "Lee"), "Some value", 123, 777L);

    /* when */
    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> actual =
      Tuples.tuple(999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date,
          Arrays.asList("Name", "Kevin", "Lee"), "Some value", 123, 777L);

    /* then */
    @SuppressWarnings("boxing")
    final Integer actualHashCode = actual.hashCode();
    @SuppressWarnings("boxing")
    final Integer expectedHashCode =
      hash(expected.getValue1(), expected.getValue2(), expected.getValue3(), expected.getValue4(),
          expected.getValue5(), expected.getValue6(), expected.getValue7(), expected.getValue8(), expected.getValue9(),
          expected.getValue10());
    assertThat(actualHashCode).isEqualTo(expectedHashCode);

    assertThat(actual).isEqualTo(expected);

    assertThat(actual.getValue1()).isEqualTo(expected.getValue1());
    assertThat(actual.getValue2()).isEqualTo(expected.getValue2());
    assertThat(actual.getValue3()).isEqualTo(expected.getValue3());
    assertThat(actual.getValue4()).isEqualTo(expected.getValue4());
    assertThat(actual.getValue5()).isEqualTo(expected.getValue5());
    assertThat(actual.getValue6()).isEqualTo(expected.getValue6());
    assertThat(actual.getValue7()).isEqualTo(expected.getValue7());
    assertThat(actual.getValue8()).isEqualTo(expected.getValue8());
    assertThat(actual.getValue9()).isEqualTo(expected.getValue9());
    assertThat(actual.getValue10()).isEqualTo(expected.getValue10());

    assertThat(actual._1()).isEqualTo(expected._1());
    assertThat(actual._2()).isEqualTo(expected._2());
    assertThat(actual._3()).isEqualTo(expected._3());
    assertThat(actual._4()).isEqualTo(expected._4());
    assertThat(actual._5()).isEqualTo(expected._5());
    assertThat(actual._6()).isEqualTo(expected._6());
    assertThat(actual._7()).isEqualTo(expected._7());
    assertThat(actual._8()).isEqualTo(expected._8());
    assertThat(actual._9()).isEqualTo(expected._9());
    assertThat(actual._10()).isEqualTo(expected._10());
  }

  @Test
  public final void testGetValue2()
  {
    /* given */
    final Date date = new Date();

    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> expected =
      new ImmutableTuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long>(
          999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date, Arrays.asList("Name", "Kevin",
              "Lee"), "Some value", 123, 777L);

    /* when */
    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> actual =
      Tuples.tuple(999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date,
          Arrays.asList("Name", "Kevin", "Lee"), "Some value", 123, 777L);

    /* then */
    @SuppressWarnings("boxing")
    final Integer actualHashCode = actual.hashCode();
    @SuppressWarnings("boxing")
    final Integer expectedHashCode =
      hash(expected.getValue1(), expected.getValue2(), expected.getValue3(), expected.getValue4(),
          expected.getValue5(), expected.getValue6(), expected.getValue7(), expected.getValue8(), expected.getValue9(),
          expected.getValue10());
    assertThat(actualHashCode).isEqualTo(expectedHashCode);

    assertThat(actual).isEqualTo(expected);

    assertThat(actual.getValue1()).isEqualTo(expected.getValue1());
    assertThat(actual.getValue2()).isEqualTo(expected.getValue2());
    assertThat(actual.getValue3()).isEqualTo(expected.getValue3());
    assertThat(actual.getValue4()).isEqualTo(expected.getValue4());
    assertThat(actual.getValue5()).isEqualTo(expected.getValue5());
    assertThat(actual.getValue6()).isEqualTo(expected.getValue6());
    assertThat(actual.getValue7()).isEqualTo(expected.getValue7());
    assertThat(actual.getValue8()).isEqualTo(expected.getValue8());
    assertThat(actual.getValue9()).isEqualTo(expected.getValue9());
    assertThat(actual.getValue10()).isEqualTo(expected.getValue10());

    assertThat(actual._1()).isEqualTo(expected._1());
    assertThat(actual._2()).isEqualTo(expected._2());
    assertThat(actual._3()).isEqualTo(expected._3());
    assertThat(actual._4()).isEqualTo(expected._4());
    assertThat(actual._5()).isEqualTo(expected._5());
    assertThat(actual._6()).isEqualTo(expected._6());
    assertThat(actual._7()).isEqualTo(expected._7());
    assertThat(actual._8()).isEqualTo(expected._8());
    assertThat(actual._9()).isEqualTo(expected._9());
    assertThat(actual._10()).isEqualTo(expected._10());
  }

  @Test
  public final void testGetValue3()
  {
    /* given */
    final Date date = new Date();

    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> expected =
      new ImmutableTuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long>(
          999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date, Arrays.asList("Name", "Kevin",
              "Lee"), "Some value", 123, 777L);

    /* when */
    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> actual =
      Tuples.tuple(999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date,
          Arrays.asList("Name", "Kevin", "Lee"), "Some value", 123, 777L);

    /* then */
    @SuppressWarnings("boxing")
    final Integer actualHashCode = actual.hashCode();
    @SuppressWarnings("boxing")
    final Integer expectedHashCode =
      hash(expected.getValue1(), expected.getValue2(), expected.getValue3(), expected.getValue4(),
          expected.getValue5(), expected.getValue6(), expected.getValue7(), expected.getValue8(), expected.getValue9(),
          expected.getValue10());
    assertThat(actualHashCode).isEqualTo(expectedHashCode);

    assertThat(actual).isEqualTo(expected);

    assertThat(actual.getValue1()).isEqualTo(expected.getValue1());
    assertThat(actual.getValue2()).isEqualTo(expected.getValue2());
    assertThat(actual.getValue3()).isEqualTo(expected.getValue3());
    assertThat(actual.getValue4()).isEqualTo(expected.getValue4());
    assertThat(actual.getValue5()).isEqualTo(expected.getValue5());
    assertThat(actual.getValue6()).isEqualTo(expected.getValue6());
    assertThat(actual.getValue7()).isEqualTo(expected.getValue7());
    assertThat(actual.getValue8()).isEqualTo(expected.getValue8());
    assertThat(actual.getValue9()).isEqualTo(expected.getValue9());
    assertThat(actual.getValue10()).isEqualTo(expected.getValue10());

    assertThat(actual._1()).isEqualTo(expected._1());
    assertThat(actual._2()).isEqualTo(expected._2());
    assertThat(actual._3()).isEqualTo(expected._3());
    assertThat(actual._4()).isEqualTo(expected._4());
    assertThat(actual._5()).isEqualTo(expected._5());
    assertThat(actual._6()).isEqualTo(expected._6());
    assertThat(actual._7()).isEqualTo(expected._7());
    assertThat(actual._8()).isEqualTo(expected._8());
    assertThat(actual._9()).isEqualTo(expected._9());
    assertThat(actual._10()).isEqualTo(expected._10());
  }

  @Test
  public final void testGetValue4()
  {
    /* given */
    final Date date = new Date();

    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> expected =
      new ImmutableTuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long>(
          999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date, Arrays.asList("Name", "Kevin",
              "Lee"), "Some value", 123, 777L);

    /* when */
    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> actual =
      Tuples.tuple(999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date,
          Arrays.asList("Name", "Kevin", "Lee"), "Some value", 123, 777L);

    /* then */
    @SuppressWarnings("boxing")
    final Integer actualHashCode = actual.hashCode();
    @SuppressWarnings("boxing")
    final Integer expectedHashCode =
      hash(expected.getValue1(), expected.getValue2(), expected.getValue3(), expected.getValue4(),
          expected.getValue5(), expected.getValue6(), expected.getValue7(), expected.getValue8(), expected.getValue9(),
          expected.getValue10());
    assertThat(actualHashCode).isEqualTo(expectedHashCode);

    assertThat(actual).isEqualTo(expected);

    assertThat(actual.getValue1()).isEqualTo(expected.getValue1());
    assertThat(actual.getValue2()).isEqualTo(expected.getValue2());
    assertThat(actual.getValue3()).isEqualTo(expected.getValue3());
    assertThat(actual.getValue4()).isEqualTo(expected.getValue4());
    assertThat(actual.getValue5()).isEqualTo(expected.getValue5());
    assertThat(actual.getValue6()).isEqualTo(expected.getValue6());
    assertThat(actual.getValue7()).isEqualTo(expected.getValue7());
    assertThat(actual.getValue8()).isEqualTo(expected.getValue8());
    assertThat(actual.getValue9()).isEqualTo(expected.getValue9());
    assertThat(actual.getValue10()).isEqualTo(expected.getValue10());

    assertThat(actual._1()).isEqualTo(expected._1());
    assertThat(actual._2()).isEqualTo(expected._2());
    assertThat(actual._3()).isEqualTo(expected._3());
    assertThat(actual._4()).isEqualTo(expected._4());
    assertThat(actual._5()).isEqualTo(expected._5());
    assertThat(actual._6()).isEqualTo(expected._6());
    assertThat(actual._7()).isEqualTo(expected._7());
    assertThat(actual._8()).isEqualTo(expected._8());
    assertThat(actual._9()).isEqualTo(expected._9());
    assertThat(actual._10()).isEqualTo(expected._10());
  }

  @Test
  public final void testGetValue5()
  {
    /* given */
    final Date date = new Date();

    @SuppressWarnings("boxing")
    final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> expected =
      new ImmutableTuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long>(
          999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date, Arrays.asList("Name", "Kevin",
              "Lee"), "Some value", 123, 777L);

    /* when */

Answer: @SuppressWarnings("boxing")

<think>
In each test method, after the /* when */ comment the code creates the actual tuple using Tuples.tuple with the same values as the expected tuple. The next line should be the @SuppressWarnings annotation and the declaration of the actual variable, matching the generic types and values used previously.
</think>
@SuppressWarnings("boxing")
final Tuple10<Integer, String, Boolean, BigInteger, BigDecimal, Date, List<String>, String, Integer, Long> actual =
  Tuples.tuple(999, "Kevin", true, BigInteger.valueOf(555L), new BigDecimal("1234.59"), date,
      Arrays.asList("Name", "Kevin", "Lee"), "Some value", 123, 777L);