|
91 | 91 | import java.io.IOException; |
92 | 92 | import java.net.MalformedURLException; |
93 | 93 | import java.net.URL; |
| 94 | +import java.nio.charset.StandardCharsets; |
94 | 95 | import java.nio.file.Files; |
95 | 96 | import java.nio.file.Paths; |
96 | 97 | import java.time.Duration; |
@@ -1817,6 +1818,82 @@ public Builder setExperimentalHost(String host) { |
1817 | 1818 | return this; |
1818 | 1819 | } |
1819 | 1820 |
|
| 1821 | + |
| 1822 | + /** |
| 1823 | + * Authenticates to Spanner Omni using the provided username and password file, and configures |
| 1824 | + * the resulting token for use in subsequent Spanner API calls. The endpoint must be set on the |
| 1825 | + * builder before calling this method. |
| 1826 | + * |
| 1827 | + * @param username The username for login. |
| 1828 | + * @param passwordFile The path to a file containing the password. |
| 1829 | + * @return this builder |
| 1830 | + */ |
| 1831 | + public Builder login(String username, String passwordFile) { |
| 1832 | + return login(username, passwordFile, true); |
| 1833 | + } |
| 1834 | + |
| 1835 | + /** |
| 1836 | + * Authenticates to Spanner Omni using the provided username and password file, and configures |
| 1837 | + * the resulting token for use in subsequent Spanner API calls. The endpoint must be set on the |
| 1838 | + * builder before calling this method. |
| 1839 | + * |
| 1840 | + * @param username The username for login. |
| 1841 | + * @param passwordFile The path to a file containing the password. |
| 1842 | + * @param backgroundRefresh Whether to proactively refresh the token in a background thread before it expires. If false, GAX still triggers a synchronous inline refresh upon UNAUTHENTICATED error. |
| 1843 | + * @return this builder |
| 1844 | + */ |
| 1845 | + public Builder login(String username, String passwordFile, boolean backgroundRefresh) { |
| 1846 | + try { |
| 1847 | + byte[] rawBytes = Files.readAllBytes(Paths.get(passwordFile)); |
| 1848 | + int len = rawBytes.length; |
| 1849 | + while (len > 0 && (rawBytes[len - 1] == '\n' || rawBytes[len - 1] == '\r')) { |
| 1850 | + len--; |
| 1851 | + } |
| 1852 | + byte[] passwordBytes = new byte[len]; |
| 1853 | + System.arraycopy(rawBytes, 0, passwordBytes, 0, len); |
| 1854 | + return loginWithPasswordBytes(username, passwordBytes, backgroundRefresh); |
| 1855 | + } catch (IOException e) { |
| 1856 | + throw SpannerExceptionFactory.newSpannerException( |
| 1857 | + ErrorCode.NOT_FOUND, "Could not read password file: " + passwordFile, e); |
| 1858 | + } |
| 1859 | + } |
| 1860 | + |
| 1861 | + /** |
| 1862 | + * Authenticates to Spanner Omni using the provided username and password, and configures the |
| 1863 | + * resulting token for use in subsequent Spanner API calls. The endpoint must be set on the |
| 1864 | + * builder before calling this method. |
| 1865 | + * |
| 1866 | + * @param username The username for login. |
| 1867 | + * @param password The password for login. |
| 1868 | + * @return this builder |
| 1869 | + */ |
| 1870 | + public Builder loginWithPassword(String username, String password) { |
| 1871 | + return loginWithPassword(username, password, true); |
| 1872 | + } |
| 1873 | + |
| 1874 | + /** |
| 1875 | + * Authenticates to Spanner Omni using the provided username and password, and configures the |
| 1876 | + * resulting token for use in subsequent Spanner API calls. The endpoint must be set on the |
| 1877 | + * builder before calling this method. |
| 1878 | + * |
| 1879 | + * @param username The username for login. |
| 1880 | + * @param password The password for login. |
| 1881 | + * @param backgroundRefresh Whether to proactively refresh the token in a background thread before it expires. If false, GAX still triggers a synchronous inline refresh upon UNAUTHENTICATED error. |
| 1882 | + * @return this builder |
| 1883 | + */ |
| 1884 | + public Builder loginWithPassword(String username, String password, boolean backgroundRefresh) { |
| 1885 | + return loginWithPasswordBytes(username, password.getBytes(StandardCharsets.UTF_8), backgroundRefresh); |
| 1886 | + } |
| 1887 | + |
| 1888 | + private Builder loginWithPasswordBytes(String username, byte[] password, boolean backgroundRefresh) { |
| 1889 | + if (this.experimentalHost == null) { |
| 1890 | + throw new IllegalStateException("Endpoint must be set before calling login."); |
| 1891 | + } |
| 1892 | + String target = this.experimentalHost.replaceFirst("^https?://", ""); |
| 1893 | + super.setCredentials(new com.google.cloud.spanner.omni.SpannerOmniCredentials(username, password, target, backgroundRefresh)); |
| 1894 | + return this; |
| 1895 | + } |
| 1896 | + |
1820 | 1897 | /** Enables gRPC-GCP extension with the default settings. This option is enabled by default. */ |
1821 | 1898 | public Builder enableGrpcGcpExtension() { |
1822 | 1899 | return this.enableGrpcGcpExtension(null); |
|
0 commit comments