http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/client/src/main/java/org/apache/atlas/security/SecureClientUtils.java ---------------------------------------------------------------------- diff --git a/client/src/main/java/org/apache/atlas/security/SecureClientUtils.java b/client/src/main/java/org/apache/atlas/security/SecureClientUtils.java deleted file mode 100644 index d5392b2..0000000 --- a/client/src/main/java/org/apache/atlas/security/SecureClientUtils.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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.atlas.security; - -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory; -import com.sun.jersey.client.urlconnection.URLConnectionClientHandler; -import org.apache.atlas.AtlasException; -import org.apache.commons.lang.StringUtils; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.security.UserGroupInformation; -import org.apache.hadoop.security.alias.CredentialProviderFactory; -import org.apache.hadoop.security.authentication.client.Authenticator; -import org.apache.hadoop.security.authentication.client.ConnectionConfigurator; -import org.apache.hadoop.security.ssl.SSLFactory; -import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticatedURL; -import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticator; -import org.apache.hadoop.security.token.delegation.web.KerberosDelegationTokenAuthenticator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSocketFactory; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.security.GeneralSecurityException; -import java.security.PrivilegedExceptionAction; - -import static org.apache.atlas.security.SecurityProperties.CERT_STORES_CREDENTIAL_PROVIDER_PATH; -import static org.apache.atlas.security.SecurityProperties.CLIENT_AUTH_KEY; -import static org.apache.atlas.security.SecurityProperties.KEYSTORE_FILE_KEY; -import static org.apache.atlas.security.SecurityProperties.TRUSTSTORE_FILE_KEY; - -/** - * - */ -public class SecureClientUtils { - - public final static int DEFAULT_SOCKET_TIMEOUT_IN_MSECS = 1 * 60 * 1000; // 1 minute - private static final Logger LOG = LoggerFactory.getLogger(SecureClientUtils.class); - - - public static URLConnectionClientHandler getClientConnectionHandler(DefaultClientConfig config, - org.apache.commons.configuration.Configuration clientConfig, String doAsUser, - final UserGroupInformation ugi) { - config.getProperties().put(URLConnectionClientHandler.PROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND, true); - Configuration conf = new Configuration(); - conf.addResource(conf.get(SSLFactory.SSL_CLIENT_CONF_KEY, SecurityProperties.SSL_CLIENT_PROPERTIES)); - UserGroupInformation.setConfiguration(conf); - final ConnectionConfigurator connConfigurator = newConnConfigurator(conf); - - Authenticator authenticator = new KerberosDelegationTokenAuthenticator(); - - authenticator.setConnectionConfigurator(connConfigurator); - final DelegationTokenAuthenticator finalAuthenticator = (DelegationTokenAuthenticator) authenticator; - final DelegationTokenAuthenticatedURL.Token token = new DelegationTokenAuthenticatedURL.Token(); - HttpURLConnectionFactory httpURLConnectionFactory = null; - try { - UserGroupInformation ugiToUse = ugi != null ? ugi : UserGroupInformation.getCurrentUser(); - final UserGroupInformation actualUgi = - (ugiToUse.getAuthenticationMethod() == UserGroupInformation.AuthenticationMethod.PROXY) - ? ugiToUse.getRealUser() : ugiToUse; - LOG.info("Real User: {}, is from ticket cache? {}", actualUgi, actualUgi.isLoginTicketBased()); - if (StringUtils.isEmpty(doAsUser)) { - doAsUser = actualUgi.getShortUserName(); - } - LOG.info("doAsUser: {}", doAsUser); - final String finalDoAsUser = doAsUser; - httpURLConnectionFactory = new HttpURLConnectionFactory() { - @Override - public HttpURLConnection getHttpURLConnection(final URL url) throws IOException { - try { - return actualUgi.doAs(new PrivilegedExceptionAction<HttpURLConnection>() { - @Override - public HttpURLConnection run() throws Exception { - try { - return new DelegationTokenAuthenticatedURL(finalAuthenticator, connConfigurator) - .openConnection(url, token, finalDoAsUser); - } catch (Exception e) { - throw new IOException(e); - } - } - }); - } catch (Exception e) { - if (e instanceof IOException) { - throw (IOException) e; - } else { - throw new IOException(e); - } - } - } - }; - } catch (IOException e) { - LOG.warn("Error obtaining user", e); - } - - return new URLConnectionClientHandler(httpURLConnectionFactory); - } - - private final static ConnectionConfigurator DEFAULT_TIMEOUT_CONN_CONFIGURATOR = new ConnectionConfigurator() { - @Override - public HttpURLConnection configure(HttpURLConnection conn) throws IOException { - setTimeouts(conn, DEFAULT_SOCKET_TIMEOUT_IN_MSECS); - return conn; - } - }; - - private static ConnectionConfigurator newConnConfigurator(Configuration conf) { - try { - return newSslConnConfigurator(DEFAULT_SOCKET_TIMEOUT_IN_MSECS, conf); - } catch (Exception e) { - LOG.debug("Cannot load customized ssl related configuration. " + "Fallback to system-generic settings.", e); - return DEFAULT_TIMEOUT_CONN_CONFIGURATOR; - } - } - - private static ConnectionConfigurator newSslConnConfigurator(final int timeout, Configuration conf) - throws IOException, GeneralSecurityException { - final SSLFactory factory; - final SSLSocketFactory sf; - final HostnameVerifier hv; - - factory = new SSLFactory(SSLFactory.Mode.CLIENT, conf); - factory.init(); - sf = factory.createSSLSocketFactory(); - hv = factory.getHostnameVerifier(); - - return new ConnectionConfigurator() { - @Override - public HttpURLConnection configure(HttpURLConnection conn) throws IOException { - if (conn instanceof HttpsURLConnection) { - HttpsURLConnection c = (HttpsURLConnection) conn; - c.setSSLSocketFactory(sf); - c.setHostnameVerifier(hv); - } - setTimeouts(conn, timeout); - return conn; - } - }; - } - - private static void setTimeouts(URLConnection connection, int socketTimeout) { - connection.setConnectTimeout(socketTimeout); - connection.setReadTimeout(socketTimeout); - } - - private static File getSSLClientFile() throws AtlasException { - String confLocation = System.getProperty("atlas.conf"); - File sslDir; - try { - if (confLocation == null) { - String persistDir = null; - URL resource = SecureClientUtils.class.getResource("/"); - if (resource != null) { - persistDir = resource.toURI().getPath(); - } - assert persistDir != null; - sslDir = new File(persistDir); - } else { - sslDir = new File(confLocation); - } - LOG.info("ssl-client.xml will be created in {}", sslDir); - } catch (Exception e) { - throw new AtlasException("Failed to find client configuration directory", e); - } - return new File(sslDir, SecurityProperties.SSL_CLIENT_PROPERTIES); - } - - public static void persistSSLClientConfiguration(org.apache.commons.configuration.Configuration clientConfig) - throws AtlasException, IOException { - //trust settings - Configuration configuration = new Configuration(false); - File sslClientFile = getSSLClientFile(); - if (!sslClientFile.exists()) { - configuration.set("ssl.client.truststore.type", "jks"); - configuration.set("ssl.client.truststore.location", clientConfig.getString(TRUSTSTORE_FILE_KEY)); - if (clientConfig.getBoolean(CLIENT_AUTH_KEY, false)) { - // need to get client key properties - configuration.set("ssl.client.keystore.location", clientConfig.getString(KEYSTORE_FILE_KEY)); - configuration.set("ssl.client.keystore.type", "jks"); - } - // add the configured credential provider - configuration.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, - clientConfig.getString(CERT_STORES_CREDENTIAL_PROVIDER_PATH)); - String hostnameVerifier = clientConfig.getString(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY); - if (hostnameVerifier != null) { - configuration.set(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, hostnameVerifier); - } - - configuration.writeXml(new FileWriter(sslClientFile)); - } - } - - public static URLConnectionClientHandler getUrlConnectionClientHandler() { - return new URLConnectionClientHandler(new HttpURLConnectionFactory() { - @Override - public HttpURLConnection getHttpURLConnection(URL url) - throws IOException { - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - - if (connection instanceof HttpsURLConnection) { - LOG.debug("Attempting to configure HTTPS connection using client " - + "configuration"); - final SSLFactory factory; - final SSLSocketFactory sf; - final HostnameVerifier hv; - - try { - Configuration conf = new Configuration(); - conf.addResource(conf.get(SSLFactory.SSL_CLIENT_CONF_KEY, SecurityProperties.SSL_CLIENT_PROPERTIES)); - UserGroupInformation.setConfiguration(conf); - - HttpsURLConnection c = (HttpsURLConnection) connection; - factory = new SSLFactory(SSLFactory.Mode.CLIENT, conf); - factory.init(); - sf = factory.createSSLSocketFactory(); - hv = factory.getHostnameVerifier(); - c.setSSLSocketFactory(sf); - c.setHostnameVerifier(hv); - } catch (Exception e) { - LOG.info("Unable to configure HTTPS connection from " - + "configuration. Leveraging JDK properties."); - } - } - return connection; - } - }); - } -}
http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/client/src/test/java/org/apache/atlas/AtlasClientTest.java ---------------------------------------------------------------------- diff --git a/client/src/test/java/org/apache/atlas/AtlasClientTest.java b/client/src/test/java/org/apache/atlas/AtlasClientTest.java deleted file mode 100644 index 1d008cc..0000000 --- a/client/src/test/java/org/apache/atlas/AtlasClientTest.java +++ /dev/null @@ -1,470 +0,0 @@ -/* - * 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.atlas; - -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; -import org.apache.atlas.model.legacy.EntityResult; -import org.apache.atlas.typesystem.Referenceable; -import org.apache.atlas.typesystem.json.InstanceSerialization; -import org.apache.commons.configuration.Configuration; -import org.apache.hadoop.security.UserGroupInformation; -import org.codehaus.jettison.json.JSONObject; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriBuilder; -import java.net.ConnectException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.List; - -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.testng.Assert.*; - -public class AtlasClientTest { - - @Mock - private WebResource service; - @Mock - private WebResource.Builder resourceBuilderMock; - - @Mock - private Configuration configuration; - - @Mock - private Client client; - - @BeforeMethod - public void setup() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void shouldVerifyServerIsReady() throws AtlasServiceException { - setupRetryParams(); - - AtlasClient atlasClient = new AtlasClient(service, configuration); - - WebResource.Builder builder = setupBuilder(AtlasClient.API.VERSION, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - when(response.getEntity(String.class)).thenReturn("{\"Version\":\"version-rrelease\",\"Name\":\"apache-atlas\"," + - "\"Description\":\"Metadata Management and Data Governance Platform over Hadoop\"}"); - when(builder.method(AtlasClient.API.VERSION.getMethod(), ClientResponse.class, null)).thenReturn(response); - - assertTrue(atlasClient.isServerReady()); - } - - @Test - public void testCreateEntity() throws Exception { - setupRetryParams(); - AtlasClient atlasClient = new AtlasClient(service, configuration); - - WebResource.Builder builder = setupBuilder(AtlasClient.API.CREATE_ENTITY, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.CREATED.getStatusCode()); - - JSONObject jsonResponse = new JSONObject(new EntityResult(Arrays.asList("id"), null, null).toString()); - when(response.getEntity(String.class)).thenReturn(jsonResponse.toString()); - when(response.getLength()).thenReturn(jsonResponse.length()); - String entityJson = InstanceSerialization.toJson(new Referenceable("type"), true); - when(builder.method(anyString(), Matchers.<Class>any(), anyString())).thenReturn(response); - - List<String> ids = atlasClient.createEntity(entityJson); - assertEquals(ids.size(), 1); - assertEquals(ids.get(0), "id"); - } - - private WebResource.Builder setupBuilder(AtlasClient.API api, WebResource webResource) { - when(webResource.path(api.getPath())).thenReturn(service); - return getBuilder(service); - } - - @Test - public void shouldReturnFalseIfServerIsNotReady() throws AtlasServiceException { - setupRetryParams(); - AtlasClient atlasClient = new AtlasClient(service, configuration); - WebResource.Builder builder = setupBuilder(AtlasClient.API.VERSION, service); - when(builder.method(AtlasClient.API.VERSION.getMethod(), ClientResponse.class, null)).thenThrow( - new ClientHandlerException()); - assertFalse(atlasClient.isServerReady()); - } - - @Test - public void shouldReturnFalseIfServiceIsUnavailable() throws AtlasServiceException { - setupRetryParams(); - AtlasClient atlasClient = new AtlasClient(service, configuration); - WebResource.Builder builder = setupBuilder(AtlasClient.API.VERSION, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.SERVICE_UNAVAILABLE.getStatusCode()); - when(response.getClientResponseStatus()).thenReturn(ClientResponse.Status.SERVICE_UNAVAILABLE); - - when(builder.method(AtlasClient.API.VERSION.getMethod(), ClientResponse.class, null)).thenReturn(response); - - assertFalse(atlasClient.isServerReady()); - } - - @Test(expectedExceptions = AtlasServiceException.class) - public void shouldThrowErrorIfAnyResponseOtherThanServiceUnavailable() throws AtlasServiceException { - setupRetryParams(); - - AtlasClient atlasClient = new AtlasClient(service, configuration); - WebResource.Builder builder = setupBuilder(AtlasClient.API.VERSION, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); - when(response.getClientResponseStatus()).thenReturn(ClientResponse.Status.INTERNAL_SERVER_ERROR); - - when(builder.method(AtlasClient.API.VERSION.getMethod(), ClientResponse.class, null)).thenReturn(response); - - atlasClient.isServerReady(); - fail("Should throw exception"); - } - - @Test - public void shouldGetAdminStatus() throws AtlasServiceException { - setupRetryParams(); - - AtlasClient atlasClient = new AtlasClient(service, configuration); - - WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - String activeStatus = "{\"Status\":\"Active\"}"; - when(response.getEntity(String.class)).thenReturn(activeStatus); - when(response.getLength()).thenReturn(activeStatus.length()); - when(builder.method(AtlasClient.API.STATUS.getMethod(), ClientResponse.class, null)).thenReturn(response); - -// Fix after AtlasBaseClient -// atlasClient.setService(); - - - String status = atlasClient.getAdminStatus(); - assertEquals(status, "Active"); - } - - @Test(expectedExceptions = AtlasServiceException.class) - public void shouldReturnStatusAsUnknownOnException() throws AtlasServiceException { - setupRetryParams(); - - AtlasClient atlasClient = new AtlasClient(service, configuration); - - WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); - when(response.getClientResponseStatus()).thenReturn(ClientResponse.Status.INTERNAL_SERVER_ERROR); - when(builder.method(AtlasClient.API.STATUS.getMethod(), ClientResponse.class, null)).thenReturn(response); - - String status = atlasClient.getAdminStatus(); - fail("Should fail with AtlasServiceException"); - } - - @Test - public void shouldReturnStatusAsUnknownIfJSONIsInvalid() throws AtlasServiceException { - setupRetryParams(); - AtlasClient atlasClient = new AtlasClient(service, configuration); - - WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - when(response.getEntity(String.class)).thenReturn("{\"status\":\"Active\"}"); - when(builder.method(AtlasClient.API.STATUS.getMethod(), ClientResponse.class, null)).thenReturn(response); - - String status = atlasClient.getAdminStatus(); - assertEquals(status, AtlasClient.UNKNOWN_STATUS); - } - - @Test - public void shouldReturnBaseURLAsPassedInURL() { - AtlasClient atlasClient = new AtlasClient(service, configuration); - - String serviceURL = atlasClient.determineActiveServiceURL(new String[]{"http://localhost:21000"}, client); - assertEquals(serviceURL, "http://localhost:21000"); - } - - @Test - public void shouldSelectActiveAmongMultipleServersIfHAIsEnabled() { - setupRetryParams(); - - when(client.resource(UriBuilder.fromUri("http://localhost:31000").build())).thenReturn(service); - when(client.resource(UriBuilder.fromUri("http://localhost:41000").build())).thenReturn(service); - WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, service); - ClientResponse firstResponse = mock(ClientResponse.class); - when(firstResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - String passiveStatus = "{\"Status\":\"PASSIVE\"}"; - when(firstResponse.getEntity(String.class)).thenReturn(passiveStatus); - when(firstResponse.getLength()).thenReturn(passiveStatus.length()); - ClientResponse secondResponse = mock(ClientResponse.class); - when(secondResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - String activeStatus = "{\"Status\":\"ACTIVE\"}"; - when(secondResponse.getEntity(String.class)).thenReturn(activeStatus); - when(secondResponse.getLength()).thenReturn(activeStatus.length()); - when(builder.method(AtlasClient.API.STATUS.getMethod(), ClientResponse.class, null)). - thenReturn(firstResponse).thenReturn(firstResponse).thenReturn(firstResponse). - thenReturn(secondResponse); - - AtlasClient atlasClient = new AtlasClient(service, configuration); - - String serviceURL = atlasClient.determineActiveServiceURL( - new String[]{"http://localhost:31000", "http://localhost:41000"}, - client); - assertEquals(serviceURL, "http://localhost:41000"); - } - - @Test - public void shouldRetryUntilServiceBecomesActive() { - setupRetryParams(); - - when(client.resource(UriBuilder.fromUri("http://localhost:31000").build())).thenReturn(service); - WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - when(response.getEntity(String.class)).thenReturn("{\"Status\":\"BECOMING_ACTIVE\"}"); - ClientResponse nextResponse = mock(ClientResponse.class); - when(nextResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - String activeStatus = "{\"Status\":\"ACTIVE\"}"; - when(response.getEntity(String.class)).thenReturn(activeStatus); - when(response.getLength()).thenReturn(activeStatus.length()); - when(builder.method(AtlasClient.API.STATUS.getMethod(), ClientResponse.class, null)). - thenReturn(response).thenReturn(response).thenReturn(nextResponse); - - AtlasClient atlasClient = new AtlasClient(service, configuration); - - String serviceURL = atlasClient.determineActiveServiceURL( - new String[] {"http://localhost:31000","http://localhost:41000"}, - client); - assertEquals(serviceURL, "http://localhost:31000"); - } - - @Test - public void shouldRetryIfCannotConnectToServiceInitially() { - setupRetryParams(); - - when(client.resource(UriBuilder.fromUri("http://localhost:31000").build())).thenReturn(service); - WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - when(response.getEntity(String.class)).thenReturn("{\"Status\":\"BECOMING_ACTIVE\"}"); - ClientResponse nextResponse = mock(ClientResponse.class); - when(nextResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - String activeStatus = "{\"Status\":\"ACTIVE\"}"; - when(response.getEntity(String.class)).thenReturn(activeStatus); - when(response.getLength()).thenReturn(activeStatus.length()); - when(builder.method(AtlasClient.API.STATUS.getMethod(), ClientResponse.class, null)). - thenThrow(new ClientHandlerException("Simulating connection exception")). - thenReturn(response). - thenReturn(nextResponse); - - AtlasClient atlasClient = new AtlasClient(service, configuration); - atlasClient.setService(service); - atlasClient.setConfiguration(configuration); - - String serviceURL = atlasClient.determineActiveServiceURL( - new String[] {"http://localhost:31000","http://localhost:41000"}, - client); - assertEquals(serviceURL, "http://localhost:31000"); - } - - @Test(expectedExceptions = IllegalArgumentException.class) - public void shouldThrowExceptionIfActiveServerIsNotFound() { - setupRetryParams(); - - when(client.resource(UriBuilder.fromUri("http://localhost:31000").build())).thenReturn(service); - WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, service); - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - when(response.getEntity(String.class)).thenReturn("{\"Status\":\"BECOMING_ACTIVE\"}"); - when(builder.method(AtlasClient.API.STATUS.getMethod(), ClientResponse.class, null)). - thenThrow(new ClientHandlerException("Simulating connection exception")). - thenReturn(response). - thenReturn(response); - - AtlasClient atlasClient = new AtlasClient(service, configuration); - - String serviceURL = atlasClient.determineActiveServiceURL( - new String[] {"http://localhost:31000","http://localhost:41000"}, - client); - assertNull(serviceURL); - } - - @Test - public void shouldRetryAPICallsOnClientHandlerException() throws AtlasServiceException, URISyntaxException { - setupRetryParams(); - - ResourceCreator resourceCreator = mock(ResourceCreator.class); - WebResource resourceObject = mock(WebResource.class); - when(resourceObject.getURI()). - thenReturn(new URI("http://localhost:31000/api/atlas/types")). - thenReturn(new URI("http://localhost:41000/api/atlas/types")). - thenReturn(new URI("http://localhost:41000/api/atlas/types")); - - WebResource.Builder builder = getBuilder(resourceObject); - - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - String activeStatus = "{\"Status\":\"ACTIVE\"}"; - when(response.getEntity(String.class)).thenReturn(activeStatus); - when(response.getLength()).thenReturn(activeStatus.length()); - - when(builder.method(AtlasClient.API.LIST_TYPES.getMethod(), ClientResponse.class, null)). - thenThrow(new ClientHandlerException("simulating exception in calling API", new ConnectException())). - thenReturn(response); - - when(resourceCreator.createResource()).thenReturn(resourceObject); - - AtlasClient atlasClient = getClientForTest("http://localhost:31000","http://localhost:41000"); - - atlasClient.setService(service); - atlasClient.setConfiguration(configuration); - - atlasClient.callAPIWithRetries(AtlasClient.API.LIST_TYPES, null, resourceCreator); - - verify(client).destroy(); - verify(client).resource(UriBuilder.fromUri("http://localhost:31000").build()); - verify(client).resource(UriBuilder.fromUri("http://localhost:41000").build()); - } - - @Test - public void shouldRetryWithSameClientIfSingleAddressIsUsed() throws URISyntaxException, AtlasServiceException { - setupRetryParams(); - - ResourceCreator resourceCreator = mock(ResourceCreator.class); - WebResource resourceObject = mock(WebResource.class); - when(resourceObject.getURI()). - thenReturn(new URI("http://localhost:31000/api/atlas/types")); - - WebResource.Builder builder = getBuilder(resourceObject); - - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - String activeStatus = "{\"Status\":\"ACTIVE\"}"; - when(response.getEntity(String.class)).thenReturn(activeStatus); - when(response.getLength()).thenReturn(activeStatus.length()); - - when(builder.method(AtlasClient.API.LIST_TYPES.getMethod(), ClientResponse.class, null)). - thenThrow(new ClientHandlerException("simulating exception in calling API", new ConnectException())). - thenReturn(response); - - when(resourceCreator.createResource()).thenReturn(resourceObject); - when(configuration.getString("atlas.http.authentication.type", "simple")).thenReturn("simple"); - - AtlasClient atlasClient = getClientForTest("http://localhost:31000"); - - atlasClient.setService(resourceObject); - atlasClient.setConfiguration(configuration); - - atlasClient.callAPIWithRetries(AtlasClient.API.LIST_TYPES, null, resourceCreator); - - verify(client).destroy(); - verify(client, times(2)).resource(UriBuilder.fromUri("http://localhost:31000").build()); - } - - @Test - public void shouldRetryAPICallsOnServiceUnavailable() throws AtlasServiceException, URISyntaxException { - setupRetryParams(); - - ResourceCreator resourceCreator = mock(ResourceCreator.class); - WebResource resourceObject = mock(WebResource.class); - when(resourceObject.getURI()). - thenReturn(new URI("http://localhost:31000/api/atlas/types")). - thenReturn(new URI("http://localhost:41000/api/atlas/types")). - thenReturn(new URI("http://localhost:41000/api/atlas/types")); - - WebResource.Builder builder = getBuilder(resourceObject); - - ClientResponse firstResponse = mock(ClientResponse.class); - when(firstResponse.getStatus()).thenReturn(Response.Status.SERVICE_UNAVAILABLE.getStatusCode()); - when(firstResponse.getClientResponseStatus()).thenReturn(ClientResponse.Status.SERVICE_UNAVAILABLE); - - ClientResponse response = mock(ClientResponse.class); - when(response.getStatus()).thenReturn(Response.Status.OK.getStatusCode()); - String activeStatus = "{\"Status\":\"ACTIVE\"}"; - when(response.getEntity(String.class)).thenReturn(activeStatus); - when(response.getLength()).thenReturn(activeStatus.length()); - - when(builder.method(AtlasClient.API.LIST_TYPES.getMethod(), ClientResponse.class, null)). - thenThrow(new ClientHandlerException("simulating exception in calling API", new ConnectException())). - thenReturn(firstResponse). - thenReturn(response); - - when(resourceCreator.createResource()).thenReturn(resourceObject); - - AtlasClient atlasClient = getClientForTest("http://localhost:31000","http://localhost:41000"); - atlasClient.setService(resourceObject); - atlasClient.setConfiguration(configuration); - - atlasClient.callAPIWithRetries(AtlasClient.API.LIST_TYPES, null, resourceCreator); - - - verify(client).destroy(); - verify(client).resource(UriBuilder.fromUri("http://localhost:31000").build()); - verify(client).resource(UriBuilder.fromUri("http://localhost:41000").build()); - } - - private WebResource.Builder getBuilder(WebResource resourceObject) { - when(resourceObject.getRequestBuilder()).thenReturn(resourceBuilderMock); - when(resourceObject.path(anyString())).thenReturn(resourceObject); - when(resourceBuilderMock.accept(AtlasBaseClient.JSON_MEDIA_TYPE)).thenReturn(resourceBuilderMock); - when(resourceBuilderMock.type(AtlasBaseClient.JSON_MEDIA_TYPE)).thenReturn(resourceBuilderMock); - return resourceBuilderMock; - } - - private void setupRetryParams() { - when(configuration.getInt(AtlasClient.ATLAS_CLIENT_HA_RETRIES_KEY, AtlasClient.DEFAULT_NUM_RETRIES)). - thenReturn(3); - when(configuration.getInt(AtlasClient.ATLAS_CLIENT_HA_SLEEP_INTERVAL_MS_KEY, - AtlasClient.DEFAULT_SLEEP_BETWEEN_RETRIES_MS)). - thenReturn(1); - } - - private AtlasClient getClientForTest(final String... baseUrls) { - return new AtlasClient((UserGroupInformation)null, (String)null, baseUrls) { - boolean firstCall = true; - @Override - protected String determineActiveServiceURL(String[] baseUrls, Client client) { - String returnUrl = baseUrls[0]; - if (baseUrls.length > 1 && !firstCall) { - returnUrl = baseUrls[1]; - } - firstCall = false; - return returnUrl; - } - - @Override - protected Configuration getClientProperties() { - return configuration; - } - - @Override - protected Client getClient(Configuration configuration, UserGroupInformation ugi, String doAsUser) { - return client; - } - }; - } -} http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/pom.xml ---------------------------------------------------------------------- diff --git a/common/pom.xml b/common/pom.xml index e5f901c..6c7521f 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -77,5 +77,10 @@ <artifactId>guava</artifactId> <version>${guava.version}</version> </dependency> + + <dependency> + <groupId>org.apache.atlas</groupId> + <artifactId>atlas-intg</artifactId> + </dependency> </dependencies> </project> http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/main/java/org/apache/atlas/ApplicationProperties.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/atlas/ApplicationProperties.java b/common/src/main/java/org/apache/atlas/ApplicationProperties.java deleted file mode 100644 index a35bdfe..0000000 --- a/common/src/main/java/org/apache/atlas/ApplicationProperties.java +++ /dev/null @@ -1,203 +0,0 @@ -/** - * 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.atlas; - -import org.apache.atlas.security.InMemoryJAASConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.net.URL; -import java.util.Iterator; - -/** - * Application properties used by Atlas. - */ -public final class ApplicationProperties extends PropertiesConfiguration { - public static final String ATLAS_CONFIGURATION_DIRECTORY_PROPERTY = "atlas.conf"; - - private static final Logger LOG = LoggerFactory.getLogger(ApplicationProperties.class); - - public static final String APPLICATION_PROPERTIES = "atlas-application.properties"; - - private static volatile Configuration instance = null; - - private ApplicationProperties(URL url) throws ConfigurationException { - super(url); - } - - public static void forceReload() { - if (instance != null) { - synchronized (ApplicationProperties.class) { - if (instance != null) { - instance = null; - } - } - } - } - - public static Configuration get() throws AtlasException { - if (instance == null) { - synchronized (ApplicationProperties.class) { - if (instance == null) { - instance = get(APPLICATION_PROPERTIES); - InMemoryJAASConfiguration.init(instance); - } - } - } - return instance; - } - - public static Configuration get(String fileName) throws AtlasException { - String confLocation = System.getProperty(ATLAS_CONFIGURATION_DIRECTORY_PROPERTY); - try { - URL url = null; - - if (confLocation == null) { - LOG.info("Looking for {} in classpath", fileName); - - url = ApplicationProperties.class.getClassLoader().getResource(fileName); - - if (url == null) { - LOG.info("Looking for /{} in classpath", fileName); - - url = ApplicationProperties.class.getClassLoader().getResource("/" + fileName); - } - } else { - url = new File(confLocation, fileName).toURI().toURL(); - } - - LOG.info("Loading {} from {}", fileName, url); - - Configuration configuration = new ApplicationProperties(url).interpolatedConfiguration(); - logConfiguration(configuration); - return configuration; - } catch (Exception e) { - throw new AtlasException("Failed to load application properties", e); - } - } - - private static void logConfiguration(Configuration configuration) { - if (LOG.isDebugEnabled()) { - Iterator<String> keys = configuration.getKeys(); - LOG.debug("Configuration loaded:"); - while (keys.hasNext()) { - String key = keys.next(); - LOG.debug("{} = {}", key, configuration.getProperty(key)); - } - } - } - - public static Configuration getSubsetConfiguration(Configuration inConf, String prefix) { - return inConf.subset(prefix); - } - - public static Class getClass(Configuration configuration, String propertyName, String defaultValue, - Class assignableClass) throws AtlasException { - try { - String propertyValue = configuration.getString(propertyName, defaultValue); - Class<?> clazz = Class.forName(propertyValue); - if (assignableClass == null || assignableClass.isAssignableFrom(clazz)) { - return clazz; - } else { - String message = "Class " + clazz.getName() + " specified in property " + propertyName - + " is not assignable to class " + assignableClass.getName(); - LOG.error(message); - throw new AtlasException(message); - } - } catch (Exception e) { - throw new AtlasException(e); - } - } - - /** - * Get the specified property as an {@link InputStream}. - * If the property is not set, then the specified default filename - * is searched for in the following locations, in order of precedence: - * 1. Atlas configuration directory specified by the {@link #ATLAS_CONFIGURATION_DIRECTORY_PROPERTY} system property - * 2. relative to the working directory if {@link #ATLAS_CONFIGURATION_DIRECTORY_PROPERTY} is not set - * 3. as a classloader resource - * - * @param configuration - * @param propertyName - * @param defaultFileName name of file to use by default if specified property is not set in the configuration- if null, - * an {@link AtlasException} is thrown if the property is not set - * @return an {@link InputStream} - * @throws AtlasException if no file was found or if there was an error loading the file - */ - public static InputStream getFileAsInputStream(Configuration configuration, String propertyName, String defaultFileName) throws AtlasException { - File fileToLoad = null; - String fileName = configuration.getString(propertyName); - if (fileName == null) { - if (defaultFileName == null) { - throw new AtlasException(propertyName + " property not set and no default value specified"); - } - fileName = defaultFileName; - String atlasConfDir = System.getProperty(ATLAS_CONFIGURATION_DIRECTORY_PROPERTY); - if (atlasConfDir != null) { - // Look for default filename in Atlas config directory - fileToLoad = new File(atlasConfDir, fileName); - } - else { - // Look for default filename under the working directory - fileToLoad = new File(fileName); - } - if (LOG.isDebugEnabled()) { - LOG.debug("{} property not set - defaulting to {}", propertyName, fileToLoad.getPath()); - } - } - else { - // Look for configured filename - fileToLoad = new File(fileName); - if (LOG.isDebugEnabled()) { - LOG.debug("Using {} property setting: {}", propertyName, fileToLoad.getPath()); - } - } - - InputStream inStr = null; - if (fileToLoad.exists()) { - try { - inStr = new FileInputStream(fileToLoad); - } catch (FileNotFoundException e) { - throw new AtlasException("Error loading file " + fileName, e); - } - if (LOG.isDebugEnabled()) { - LOG.debug("Loaded file from : {}", fileToLoad.getPath()); - } - } - else { - // Look for file as class loader resource - inStr = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); - if (inStr == null) { - String msg = fileName + " not found in file system or as class loader resource"; - LOG.error(msg); - throw new AtlasException(msg); - } - if (LOG.isDebugEnabled()) { - LOG.debug("Loaded {} as resource from : {}", fileName, Thread.currentThread().getContextClassLoader().getResource(fileName).toString()); - } - } - return inStr; - } -} http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/main/java/org/apache/atlas/AtlasException.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/atlas/AtlasException.java b/common/src/main/java/org/apache/atlas/AtlasException.java deleted file mode 100644 index 45d91d4..0000000 --- a/common/src/main/java/org/apache/atlas/AtlasException.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * 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.atlas; - -/** - * Base Exception class for Atlas API. - */ -public class AtlasException extends Exception { - - public AtlasException() { - } - - public AtlasException(String message) { - super(message); - } - - public AtlasException(String message, Throwable cause) { - super(message, cause); - } - - public AtlasException(Throwable cause) { - super(cause); - } - - public AtlasException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java b/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java index a6e1689..fff104b 100644 --- a/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java +++ b/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java @@ -17,10 +17,10 @@ */ package org.apache.atlas.groovy; -import java.util.List; - import org.apache.atlas.AtlasException; +import java.util.List; + /** * Represents an arithmetic expression such as a+b. */ http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/main/java/org/apache/atlas/security/InMemoryJAASConfiguration.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/atlas/security/InMemoryJAASConfiguration.java b/common/src/main/java/org/apache/atlas/security/InMemoryJAASConfiguration.java deleted file mode 100644 index 936311b..0000000 --- a/common/src/main/java/org/apache/atlas/security/InMemoryJAASConfiguration.java +++ /dev/null @@ -1,401 +0,0 @@ -/** - * 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.atlas.security; - -import org.apache.atlas.AtlasException; -import org.apache.commons.collections.MapUtils; -import org.apache.commons.configuration.ConfigurationConverter; -import org.apache.commons.lang.ArrayUtils; -import org.apache.hadoop.security.SecurityUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.Configuration; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.SortedSet; -import java.util.StringTokenizer; -import java.util.TreeSet; - - -/** - * InMemoryJAASConfiguration - * <p> - * An utility class - which has a static method init to load all JAAS configuration from Application - * properties file (eg: atlas.properties) and set it as part of the default lookup configuration for - * all JAAS configuration lookup. - * <p> - * Example settings in jaas-application.properties: - * - * <pre class=code> - * atlas.jaas.KafkaClient.loginModuleName = com.sun.security.auth.module.Krb5LoginModule - * atlas.jaas.KafkaClient.loginModuleControlFlag = required - * atlas.jaas.KafkaClient.option.useKeyTab = true - * atlas.jaas.KafkaClient.option.storeKey = true - * atlas.jaas.KafkaClient.option.serviceName = kafka - * atlas.jaas.KafkaClient.option.keyTab = /etc/security/keytabs/kafka_client.keytab - * atlas.jaas.KafkaClient.option.principal = [email protected] - - * atlas.jaas.MyClient.0.loginModuleName = com.sun.security.auth.module.Krb5LoginModule - * atlas.jaas.MyClient.0.loginModuleControlFlag = required - * atlas.jaas.MyClient.0.option.useKeyTab = true - * atlas.jaas.MyClient.0.option.storeKey = true - * atlas.jaas.MyClient.0.option.serviceName = kafka - * atlas.jaas.MyClient.0.option.keyTab = /etc/security/keytabs/kafka_client.keytab - * atlas.jaas.MyClient.0.option.principal = [email protected] - * atlas.jaas.MyClient.1.loginModuleName = com.sun.security.auth.module.Krb5LoginModule - * atlas.jaas.MyClient.1.loginModuleControlFlag = optional - * atlas.jaas.MyClient.1.option.useKeyTab = true - * atlas.jaas.MyClient.1.option.storeKey = true - * atlas.jaas.MyClient.1.option.serviceName = kafka - * atlas.jaas.MyClient.1.option.keyTab = /etc/security/keytabs/kafka_client.keytab - * atlas.jaas.MyClient.1.option.principal = [email protected] </pre> - * - * <p> - * This will set the JAAS configuration - equivalent to the jaas.conf file entries: - * - * <pre class=code> - * KafkaClient { - * com.sun.security.auth.module.Krb5LoginModule required - * useKeyTab=true - * storeKey=true - * serviceName=kafka - * keyTab="/etc/security/keytabs/kafka_client.keytab" - * principal="[email protected]"; - * }; - * MyClient { - * com.sun.security.auth.module.Krb5LoginModule required - * useKeyTab=true - * storeKey=true - * serviceName=kafka keyTab="/etc/security/keytabs/kafka_client.keytab" - * principal="[email protected]"; - * }; - * MyClient { - * com.sun.security.auth.module.Krb5LoginModule optional - * useKeyTab=true - * storeKey=true - * serviceName=kafka - * keyTab="/etc/security/keytabs/kafka_client.keytab" - * principal="[email protected]"; - * }; </pre> - * <p> - * Here is the syntax for atlas.properties to add JAAS configuration: - * <p> - * The property name has to begin with 'atlas.jaas.' + clientId (in case of Kafka client, - * it expects the clientId to be KafkaClient). - * <p> - * The following property must be there to specify the JAAS loginModule name - * <pre> 'atlas.jaas.' + clientId + '.loginModuleName' </pre> - * <p> - * The following optional property should be set to specify the loginModuleControlFlag - * <pre> 'atlas.jaas.' + clientId + '.loginModuleControlFlag' - * Default value : required , Possible values: required, optional, sufficient, requisite </pre> - * <p> - * Then you can add additional optional parameters as options for the configuration using the following - * syntax: - * <pre> 'atlas.jaas.' + clientId + '.option.' + <optionName> = <optionValue> </pre> - * <p> - * The current setup will lookup JAAS configration from the atlas-application.properties first, - * if not available, it will delegate to the original configuration - * - */ - - -public final class InMemoryJAASConfiguration extends Configuration { - - private static final Logger LOG = LoggerFactory.getLogger(InMemoryJAASConfiguration.class); - - private static final String JAAS_CONFIG_PREFIX_PARAM = "atlas.jaas."; - private static final String JAAS_CONFIG_LOGIN_MODULE_NAME_PARAM = "loginModuleName"; - private static final String JAAS_CONFIG_LOGIN_MODULE_CONTROL_FLAG_PARAM = "loginModuleControlFlag"; - private static final String JAAS_CONFIG_LOGIN_OPTIONS_PREFIX = "option"; - private static final String JAAS_PRINCIPAL_PROP = "principal"; - private static final Map<String, String> CONFIG_SECTION_REDIRECTS = new HashMap<>(); - - private Configuration parent = null; - private Map<String, List<AppConfigurationEntry>> applicationConfigEntryMap = new HashMap<>(); - - public static void init(String propFile) throws AtlasException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> InMemoryJAASConfiguration.init({})", propFile); - } - - InputStream in = null; - - try { - Properties properties = new Properties(); - in = ClassLoader.getSystemResourceAsStream(propFile); - if (in == null) { - if (!propFile.startsWith("/")) { - in = ClassLoader.getSystemResourceAsStream("/" + propFile); - } - if (in == null) { - in = new FileInputStream(new File(propFile)); - } - } - properties.load(in); - init(properties); - } catch (IOException e) { - throw new AtlasException("Failed to load JAAS application properties", e); - } finally { - if (in != null) { - try { - in.close(); - } catch (Exception exception) { - // Ignore - } - } - } - - if (LOG.isDebugEnabled()) { - LOG.debug("<== InMemoryJAASConfiguration.init({})", propFile); - } - } - - public static void init(org.apache.commons.configuration.Configuration atlasConfiguration) throws AtlasException { - LOG.debug("==> InMemoryJAASConfiguration.init()"); - - if (atlasConfiguration != null && !atlasConfiguration.isEmpty()) { - Properties properties = ConfigurationConverter.getProperties(atlasConfiguration); - init(properties); - } else { - throw new AtlasException("Failed to load JAAS application properties: configuration NULL or empty!"); - } - - LOG.debug("<== InMemoryJAASConfiguration.init()"); - } - - public static void init(Properties properties) throws AtlasException { - LOG.debug("==> InMemoryJAASConfiguration.init()"); - - if (properties != null && MapUtils.isNotEmpty(properties)) { - InMemoryJAASConfiguration conf = new InMemoryJAASConfiguration(properties); - Configuration.setConfiguration(conf); - } else { - throw new AtlasException("Failed to load JAAS application properties: properties NULL or empty!"); - } - - LOG.debug("<== InMemoryJAASConfiguration.init()"); - } - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) { - if (LOG.isDebugEnabled()) { - LOG.debug("==> InMemoryJAASConfiguration.getAppConfigurationEntry({})", name); - } - - AppConfigurationEntry[] ret = null; - List<AppConfigurationEntry> retList = null; - String redirectedName = getConfigSectionRedirect(name); - - if (redirectedName != null) { - retList = applicationConfigEntryMap.get(redirectedName); - - if (LOG.isDebugEnabled()) { - LOG.debug("Redirected jaasConfigSection ({} -> {}): ", name, redirectedName, retList); - } - } - - if (retList == null || retList.size() == 0) { - retList = applicationConfigEntryMap.get(name); - } - - if (retList == null || retList.size() == 0) { - if (parent != null) { - ret = parent.getAppConfigurationEntry(name); - } - } else { - int sz = retList.size(); - ret = new AppConfigurationEntry[sz]; - ret = retList.toArray(ret); - } - - if (LOG.isDebugEnabled()) { - LOG.debug("<== InMemoryJAASConfiguration.getAppConfigurationEntry({}): {}", name, ArrayUtils.toString(ret)); - } - - return ret; - } - - private InMemoryJAASConfiguration(Properties prop) { - parent = Configuration.getConfiguration(); - initialize(prop); - } - - private void initialize(Properties properties) { - LOG.debug("==> InMemoryJAASConfiguration.initialize()"); - - int prefixLen = JAAS_CONFIG_PREFIX_PARAM.length(); - - Map<String, SortedSet<Integer>> jaasClients = new HashMap<>(); - for (String key : properties.stringPropertyNames()) { - if (key.startsWith(JAAS_CONFIG_PREFIX_PARAM)) { - String jaasKey = key.substring(prefixLen); - StringTokenizer tokenizer = new StringTokenizer(jaasKey, "."); - int tokenCount = tokenizer.countTokens(); - if (tokenCount > 0) { - String clientId = tokenizer.nextToken(); - SortedSet<Integer> indexList = jaasClients.get(clientId); - if (indexList == null) { - indexList = new TreeSet<>(); - jaasClients.put(clientId, indexList); - } - String indexStr = tokenizer.nextToken(); - - int indexId = isNumeric(indexStr) ? Integer.parseInt(indexStr) : -1; - - Integer clientIdIndex = Integer.valueOf(indexId); - - if (!indexList.contains(clientIdIndex)) { - indexList.add(clientIdIndex); - } - - } - } - } - for (String jaasClient : jaasClients.keySet()) { - - for (Integer index : jaasClients.get(jaasClient)) { - - String keyPrefix = JAAS_CONFIG_PREFIX_PARAM + jaasClient + "."; - - if (index > -1) { - keyPrefix = keyPrefix + String.valueOf(index) + "."; - } - - String keyParam = keyPrefix + JAAS_CONFIG_LOGIN_MODULE_NAME_PARAM; - String loginModuleName = properties.getProperty(keyParam); - - if (loginModuleName == null) { - LOG.error("Unable to add JAAS configuration for client [{}] as it is missing param [{}]. Skipping JAAS config for [{}]", jaasClient, keyParam, jaasClient); - continue; - } else { - loginModuleName = loginModuleName.trim(); - } - - keyParam = keyPrefix + JAAS_CONFIG_LOGIN_MODULE_CONTROL_FLAG_PARAM; - String controlFlag = properties.getProperty(keyParam); - - AppConfigurationEntry.LoginModuleControlFlag loginControlFlag = null; - if (controlFlag != null) { - controlFlag = controlFlag.trim().toLowerCase(); - switch (controlFlag) { - case "optional": - loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL; - break; - case "requisite": - loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUISITE; - break; - case "sufficient": - loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT; - break; - case "required": - loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUIRED; - break; - default: - String validValues = "optional|requisite|sufficient|required"; - LOG.warn("Unknown JAAS configuration value for ({}) = [{}], valid value are [{}] using the default value, REQUIRED", keyParam, controlFlag, validValues); - loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUIRED; - break; - } - } else { - LOG.warn("Unable to find JAAS configuration ({}); using the default value, REQUIRED", keyParam); - loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUIRED; - } - - - Map<String, String> options = new HashMap<>(); - String optionPrefix = keyPrefix + JAAS_CONFIG_LOGIN_OPTIONS_PREFIX + "."; - int optionPrefixLen = optionPrefix.length(); - for (String key : properties.stringPropertyNames()) { - if (key.startsWith(optionPrefix)) { - String optionKey = key.substring(optionPrefixLen); - String optionVal = properties.getProperty(key); - if (optionVal != null) { - optionVal = optionVal.trim(); - - try { - if (optionKey.equalsIgnoreCase(JAAS_PRINCIPAL_PROP)) { - optionVal = SecurityUtil.getServerPrincipal(optionVal, (String) null); - } - } catch (IOException e) { - LOG.warn("Failed to build serverPrincipal. Using provided value:[{}]", optionVal); - } - } - options.put(optionKey, optionVal); - } - } - - AppConfigurationEntry entry = new AppConfigurationEntry(loginModuleName, loginControlFlag, options); - - if (LOG.isDebugEnabled()) { - StringBuilder sb = new StringBuilder(); - sb.append("Adding client: [").append(jaasClient).append("{").append(index).append("}]\n"); - sb.append("\tloginModule: [").append(loginModuleName).append("]\n"); - sb.append("\tcontrolFlag: [").append(loginControlFlag).append("]\n"); - for (String key : options.keySet()) { - String val = options.get(key); - sb.append("\tOptions: [").append(key).append("] => [").append(val).append("]\n"); - } - LOG.debug(sb.toString()); - } - - List<AppConfigurationEntry> retList = applicationConfigEntryMap.get(jaasClient); - if (retList == null) { - retList = new ArrayList<>(); - applicationConfigEntryMap.put(jaasClient, retList); - } - - retList.add(entry); - } - } - - LOG.debug("<== InMemoryJAASConfiguration.initialize({})", applicationConfigEntryMap); - } - - private static boolean isNumeric(String str) { - return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal. - } - - public static void setConfigSectionRedirect(String name, String redirectTo) { - if (LOG.isDebugEnabled()) { - LOG.debug("setConfigSectionRedirect({}, {})", name, redirectTo); - } - - if (name != null) { - if (redirectTo != null) { - CONFIG_SECTION_REDIRECTS.put(name, redirectTo); - } else { - CONFIG_SECTION_REDIRECTS.remove(name); - } - } - } - - private static String getConfigSectionRedirect(String name) { - return name != null ? CONFIG_SECTION_REDIRECTS.get(name) : null; - } -} http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/main/java/org/apache/atlas/security/SecurityProperties.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/atlas/security/SecurityProperties.java b/common/src/main/java/org/apache/atlas/security/SecurityProperties.java deleted file mode 100644 index 2e953eb..0000000 --- a/common/src/main/java/org/apache/atlas/security/SecurityProperties.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * 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.atlas.security; - -import java.util.Arrays; -import java.util.List; - -/** - * - */ -public final class SecurityProperties { - - private SecurityProperties() { - } - - public static final String TLS_ENABLED = "atlas.enableTLS"; - public static final String KEYSTORE_FILE_KEY = "keystore.file"; - public static final String DEFAULT_KEYSTORE_FILE_LOCATION = "target/atlas.keystore"; - public static final String KEYSTORE_PASSWORD_KEY = "keystore.password"; - public static final String TRUSTSTORE_FILE_KEY = "truststore.file"; - public static final String DEFATULT_TRUSTORE_FILE_LOCATION = "target/atlas.keystore"; - public static final String TRUSTSTORE_PASSWORD_KEY = "truststore.password"; - public static final String SERVER_CERT_PASSWORD_KEY = "password"; - public static final String CLIENT_AUTH_KEY = "client.auth.enabled"; - public static final String CERT_STORES_CREDENTIAL_PROVIDER_PATH = "cert.stores.credential.provider.path"; - public static final String SSL_CLIENT_PROPERTIES = "ssl-client.xml"; - public static final String BIND_ADDRESS = "atlas.server.bind.address"; - public static final String ATLAS_SSL_EXCLUDE_CIPHER_SUITES = "atlas.ssl.exclude.cipher.suites"; - public static final List<String> DEFAULT_CIPHER_SUITES = Arrays.asList( - ".*NULL.*", ".*RC4.*", ".*MD5.*", ".*DES.*", ".*DSS.*"); - public static final String ATLAS_SSL_EXCLUDE_PROTOCOLS = "atlas.ssl.exclude.protocols"; - public static final String[] DEFAULT_EXCLUDE_PROTOCOLS = new String[] { "TLSv1", "TLSv1.1" }; - -} http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/main/java/org/apache/atlas/utils/AuthenticationUtil.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/atlas/utils/AuthenticationUtil.java b/common/src/main/java/org/apache/atlas/utils/AuthenticationUtil.java deleted file mode 100644 index 09d8085..0000000 --- a/common/src/main/java/org/apache/atlas/utils/AuthenticationUtil.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 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.atlas.utils; - -import org.apache.atlas.ApplicationProperties; -import org.apache.atlas.AtlasException; -import org.apache.commons.configuration.Configuration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.Console; - -/** - * Util class for Authentication. - */ -public final class AuthenticationUtil { - private static final Logger LOG = LoggerFactory.getLogger(AuthenticationUtil.class); - - private AuthenticationUtil() { - } - - public static boolean isKerberosAuthenticationEnabled() { - boolean isKerberosAuthenticationEnabled = false; - try { - isKerberosAuthenticationEnabled = isKerberosAuthenticationEnabled(ApplicationProperties.get()); - } catch (AtlasException e) { - LOG.error("Error while isKerberosAuthenticationEnabled ", e); - } - return isKerberosAuthenticationEnabled; - } - - public static boolean isKerberosAuthenticationEnabled(Configuration atlasConf) { - return atlasConf.getBoolean("atlas.authentication.method.kerberos", false); - } - - public static String[] getBasicAuthenticationInput() { - String username = null; - String password = null; - - try { - Console console = System.console(); - username = console.readLine("Enter username for atlas :- "); - - char[] pwdChar = console.readPassword("Enter password for atlas :- "); - if(pwdChar != null) { - password = new String(pwdChar); - } - - } catch (Exception e) { - System.out.print("Error while reading "); - System.exit(1); - } - return new String[]{username, password}; - } - -} http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java b/common/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java deleted file mode 100644 index 89e5e9b..0000000 --- a/common/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/** - * 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.atlas; - -import java.io.InputStream; - -import org.apache.commons.configuration.Configuration; -import org.testng.annotations.Test; -import static org.testng.Assert.*; - -/** - * Unit test for {@link ApplicationProperties} - * - */ -public class ApplicationPropertiesTest { - - @Test - public void testGetFileAsInputStream() throws Exception { - Configuration props = ApplicationProperties.get("test.properties"); - InputStream inStr = null; - - // configured file as class loader resource - try { - inStr = ApplicationProperties.getFileAsInputStream(props, "jaas.properties.file", null); - assertNotNull(inStr); - } - finally { - if (inStr != null) { - inStr.close(); - } - } - - // configured file from file system path - props.setProperty("jaas.properties.file", "src/test/resources/atlas-jaas.properties"); - try { - inStr = ApplicationProperties.getFileAsInputStream(props, "jaas.properties.file", null); - assertNotNull(inStr); - } - finally { - if (inStr != null) { - inStr.close(); - } - } - - // default file as class loader resource - try { - inStr = ApplicationProperties.getFileAsInputStream(props, "property.not.specified.in.config", "atlas-jaas.properties"); - assertNotNull(inStr); - } - finally { - if (inStr != null) { - inStr.close(); - } - } - - // default file relative to working directory - try { - inStr = ApplicationProperties.getFileAsInputStream(props, "property.not.specified.in.config", "src/test/resources/atlas-jaas.properties"); - assertNotNull(inStr); - } - finally { - if (inStr != null) { - inStr.close(); - } - } - - // default file relative to atlas configuration directory - String originalConfDirSetting = System.setProperty(ApplicationProperties.ATLAS_CONFIGURATION_DIRECTORY_PROPERTY, "src/test/resources"); - try { - inStr = ApplicationProperties.getFileAsInputStream(props, "property.not.specified.in.config", "atlas-jaas.properties"); - assertNotNull(inStr); - } - finally { - if (inStr != null) { - inStr.close(); - } - if (originalConfDirSetting != null) { - System.setProperty(ApplicationProperties.ATLAS_CONFIGURATION_DIRECTORY_PROPERTY, originalConfDirSetting); - } - else { - System.clearProperty(ApplicationProperties.ATLAS_CONFIGURATION_DIRECTORY_PROPERTY); - } - } - - // non-existent property and no default file - try { - inStr = ApplicationProperties.getFileAsInputStream(props, "property.not.specified.in.config", null); - fail("Expected " + AtlasException.class.getSimpleName() + " but none thrown"); - } - catch (AtlasException e) { - // good - } - finally { - if (inStr != null) { - inStr.close(); - } - } - - // configured file not found in file system or classpath - props.setProperty("jaas.properties.file", "does_not_exist.txt"); - try { - inStr = ApplicationProperties.getFileAsInputStream(props, "jaas.properties.file", null); - fail("Expected " + AtlasException.class.getSimpleName() + " but none thrown"); - } - catch (AtlasException e) { - // good - } - finally { - if (inStr != null) { - inStr.close(); - } - } - } -} http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/test/java/org/apache/atlas/security/InMemoryJAASConfigurationTest.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/atlas/security/InMemoryJAASConfigurationTest.java b/common/src/test/java/org/apache/atlas/security/InMemoryJAASConfigurationTest.java deleted file mode 100644 index b26ac7f..0000000 --- a/common/src/test/java/org/apache/atlas/security/InMemoryJAASConfigurationTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/** - * 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.atlas.security; - -import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.Configuration; - -import junit.framework.Assert; -import junit.framework.TestCase; -import org.apache.hadoop.util.StringUtils; -import org.testng.annotations.Test; - - -//Unstable test. Disabling -@Test(enabled=false) -public class InMemoryJAASConfigurationTest extends TestCase { - - private static final String ATLAS_JAAS_PROP_FILE = "atlas-jaas.properties"; - - protected void setUp() throws Exception { - super.setUp(); - try { - InMemoryJAASConfiguration.init(ATLAS_JAAS_PROP_FILE); - } catch(Throwable t) { - fail("InMemoryJAASConfiguration.init() is not expected to throw Exception:" + t); - } - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Test(enabled=false) - public void testGetAppConfigurationEntryStringForKafkaClient() { - AppConfigurationEntry[] entries = - Configuration.getConfiguration().getAppConfigurationEntry("KafkaClient"); - Assert.assertNotNull(entries); - Assert.assertEquals(1, entries.length); - String principal = (String) entries[0].getOptions().get("principal"); - Assert.assertNotNull(principal); - String[] components = principal.split("[/@]"); - Assert.assertEquals(3, components.length); - Assert.assertEquals(false, StringUtils.equalsIgnoreCase(components[1], "_HOST")); - - } - - @Test(enabled=false) - public void testGetAppConfigurationEntryStringForMyClient() { - AppConfigurationEntry[] entries = - Configuration.getConfiguration().getAppConfigurationEntry("myClient"); - Assert.assertNotNull(entries); - Assert.assertEquals(2, entries.length); - String principal = (String) entries[0].getOptions().get("principal"); - Assert.assertNotNull(principal); - String[] components = principal.split("[/@]"); - Assert.assertEquals(3, components.length); - Assert.assertEquals(true, StringUtils.equalsIgnoreCase(components[1], "abcd")); - - principal = (String) entries[1].getOptions().get("principal"); - Assert.assertNotNull(principal); - components = principal.split("[/@]"); - Assert.assertEquals(2, components.length); - } - - @Test(enabled=false) - public void testGetAppConfigurationEntryStringForUnknownClient() { - AppConfigurationEntry[] entries = - Configuration.getConfiguration().getAppConfigurationEntry("UnknownClient"); - Assert.assertNull(entries); - } - -} - http://git-wip-us.apache.org/repos/asf/atlas/blob/900bf9eb/common/src/test/java/org/apache/atlas/security/InMemoryJAASConfigurationTicketBasedKafkaClientTest.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/atlas/security/InMemoryJAASConfigurationTicketBasedKafkaClientTest.java b/common/src/test/java/org/apache/atlas/security/InMemoryJAASConfigurationTicketBasedKafkaClientTest.java deleted file mode 100644 index 3d8175f..0000000 --- a/common/src/test/java/org/apache/atlas/security/InMemoryJAASConfigurationTicketBasedKafkaClientTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * 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.atlas.security; - -import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.Configuration; - -import junit.framework.Assert; -import junit.framework.TestCase; -import org.testng.annotations.Test; - - -@Test -public class InMemoryJAASConfigurationTicketBasedKafkaClientTest extends TestCase { - - private static final String ATLAS_JAAS_PROP_FILE = "atlas-jaas.properties"; - - protected void setUp() throws Exception { - super.setUp(); - try { - InMemoryJAASConfiguration.init(ATLAS_JAAS_PROP_FILE); - InMemoryJAASConfiguration.setConfigSectionRedirect("KafkaClient", "ticketBased-KafkaClient"); - } catch (Throwable t) { - fail("InMemoryJAASConfiguration.init() is not expected to throw Exception:" + t); - } - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - - @Test - public void testGetAppConfigurationEntryStringForticketBasedKafkaClient() { - - AppConfigurationEntry[] entries = - Configuration.getConfiguration().getAppConfigurationEntry("KafkaClient"); - Assert.assertNotNull(entries); - Assert.assertEquals((String) entries[0].getOptions().get("useTicketCache"), "true"); - } - - -} -
