atlas-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From suma...@apache.org
Subject incubator-atlas git commit: ATLAS-513 Admin support for HA (yhemanth via sumasai)
Date Fri, 01 Apr 2016 18:13:27 GMT
Repository: incubator-atlas
Updated Branches:
  refs/heads/master 8bde666ba -> 0fc207196


ATLAS-513 Admin support for HA (yhemanth via sumasai)


Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/0fc20719
Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/0fc20719
Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/0fc20719

Branch: refs/heads/master
Commit: 0fc2071960f11b237b3d7c510b1d6fed6be7ee63
Parents: 8bde666
Author: Suma Shivaprasad <sumasai.shivaprasad@gmail.com>
Authored: Fri Apr 1 11:13:19 2016 -0700
Committer: Suma Shivaprasad <sumasai.shivaprasad@gmail.com>
Committed: Fri Apr 1 11:13:19 2016 -0700

----------------------------------------------------------------------
 .../java/org/apache/atlas/AtlasAdminClient.java | 112 +++++++++++++++++++
 .../main/java/org/apache/atlas/AtlasClient.java |  22 ++++
 .../java/org/apache/atlas/AtlasClientTest.java  |  58 +++++++++-
 .../java/org/apache/atlas/AtlasConstants.java   |   2 +
 distro/src/bin/atlas_admin.py                   |  40 +++++++
 distro/src/bin/atlas_client_cmdline.py          |  61 ++++++++++
 distro/src/bin/quick_start.py                   |  41 +------
 distro/src/conf/atlas-application.properties    |  13 ++-
 release-log.txt                                 |   1 +
 .../main/resources/atlas-application.properties |   4 +-
 .../atlas/web/filters/ActiveServerFilter.java   |  12 +-
 .../atlas/web/resources/AdminResource.java      |  22 ++++
 .../web/filters/ActiveServerFilterTest.java     |  31 +++++
 .../atlas/web/resources/AdminResourceTest.java  |  70 ++++++++++++
 14 files changed, 437 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/client/src/main/java/org/apache/atlas/AtlasAdminClient.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/atlas/AtlasAdminClient.java b/client/src/main/java/org/apache/atlas/AtlasAdminClient.java
new file mode 100644
index 0000000..473f72a
--- /dev/null
+++ b/client/src/main/java/org/apache/atlas/AtlasAdminClient.java
@@ -0,0 +1,112 @@
+/**
+ * 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.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.configuration.Configuration;
+
+/**
+ * An application that allows users to run admin commands against an Atlas server.
+ *
+ * The application uses {@link AtlasClient} to send REST requests to the Atlas server. The
details of connections
+ * and other configuration is specified in the Atlas properties file.
+ * Exit status of the application will be as follows:
+ * <li>0: successful execution</li>
+ * <li>1: error in options used for the application</li>
+ * <li>-1/255: application error</li>
+ */
+public class AtlasAdminClient {
+
+    private static final Option STATUS = new Option("status", false, "Get the status of an
atlas instance");
+    private static final Options OPTIONS = new Options();
+
+    private static final int INVALID_OPTIONS_STATUS = 1;
+    private static final int PROGRAM_ERROR_STATUS = -1;
+
+    static {
+        OPTIONS.addOption(STATUS);
+    }
+
+    public static void main(String[] args) throws AtlasException, ParseException {
+        AtlasAdminClient atlasAdminClient = new AtlasAdminClient();
+        int result = atlasAdminClient.run(args);
+        System.exit(result);
+    }
+
+    private int run(String[] args) throws AtlasException {
+        CommandLine commandLine = parseCommandLineOptions(args);
+        Configuration configuration = ApplicationProperties.get();
+        String atlasServerUri = configuration.getString(
+                AtlasConstants.ATLAS_REST_ADDRESS_KEY, AtlasConstants.DEFAULT_ATLAS_REST_ADDRESS);
+        AtlasClient atlasClient = new AtlasClient(atlasServerUri, null, null);
+        return handleCommand(commandLine, atlasServerUri, atlasClient);
+    }
+
+    private int handleCommand(CommandLine commandLine, String atlasServerUri, AtlasClient
atlasClient) {
+        int cmdStatus = PROGRAM_ERROR_STATUS;
+        if (commandLine.hasOption(STATUS.getOpt())) {
+            try {
+                System.out.println(atlasClient.getAdminStatus());
+                cmdStatus = 0;
+            } catch (AtlasServiceException e) {
+                System.err.println("Could not retrieve status of the server at " + atlasServerUri);
+                printStandardHttpErrorDetails(e);
+            }
+        } else {
+            System.err.println("Unsupported option. Refer to usage for valid options.");
+            printUsage(INVALID_OPTIONS_STATUS);
+        }
+        return cmdStatus;
+    }
+
+    private void printStandardHttpErrorDetails(AtlasServiceException e) {
+        System.err.println("Error details: ");
+        System.err.println("HTTP Status: " + e.getStatus().getStatusCode() + ","
+                + e.getStatus().getReasonPhrase());
+        System.err.println("Exception message: " + e.getMessage());
+    }
+
+    private CommandLine parseCommandLineOptions(String[] args) {
+        if (args.length == 0) {
+            printUsage(INVALID_OPTIONS_STATUS);
+        }
+        CommandLineParser parser = new GnuParser();
+        CommandLine commandLine = null;
+        try {
+            commandLine = parser.parse(OPTIONS, args);
+        } catch (ParseException e) {
+            System.err.println("Could not parse command line options.");
+            printUsage(INVALID_OPTIONS_STATUS);
+        }
+        return commandLine;
+    }
+
+    private void printUsage(int statusCode) {
+        HelpFormatter helpFormatter = new HelpFormatter();
+        helpFormatter.printHelp("atlas_admin.py", OPTIONS);
+        System.exit(statusCode);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/client/src/main/java/org/apache/atlas/AtlasClient.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/atlas/AtlasClient.java b/client/src/main/java/org/apache/atlas/AtlasClient.java
index 18c0569..0bb5264 100755
--- a/client/src/main/java/org/apache/atlas/AtlasClient.java
+++ b/client/src/main/java/org/apache/atlas/AtlasClient.java
@@ -70,6 +70,7 @@ public class AtlasClient {
 
     public static final String BASE_URI = "api/atlas/";
     public static final String ADMIN_VERSION = "admin/version";
+    public static final String ADMIN_STATUS = "admin/status";
     public static final String TYPES = "types";
     public static final String URI_ENTITY = "entities";
     public static final String URI_SEARCH = "discovery/search";
@@ -88,6 +89,7 @@ public class AtlasClient {
     public static final String REFERENCEABLE_ATTRIBUTE_NAME = "qualifiedName";
 
     public static final String JSON_MEDIA_TYPE = MediaType.APPLICATION_JSON + "; charset=UTF-8";
+    public static final String UNKNOWN_STATUS = "Unknown status";
 
     private WebResource service;
 
@@ -154,10 +156,30 @@ public class AtlasClient {
         }
     }
 
+    /**
+     * Return status of the service instance the client is pointing to.
+     *
+     * @return One of the values in ServiceState.ServiceStateValue or {@link #UNKNOWN_STATUS}
if there is a JSON parse
+     * exception
+     * @throws AtlasServiceException if there is a HTTP error.
+     */
+    public String getAdminStatus() throws AtlasServiceException {
+        String result = UNKNOWN_STATUS;
+        WebResource resource = getResource(API.STATUS);
+        JSONObject response = callAPIWithResource(API.STATUS, resource);
+        try {
+            result = response.getString("Status");
+        } catch (JSONException e) {
+            LOG.error("Exception while parsing admin status response. Returned response {}",
response.toString(), e);
+        }
+        return result;
+    }
+
     public enum API {
 
         //Admin operations
         VERSION(BASE_URI + ADMIN_VERSION, HttpMethod.GET, Response.Status.OK),
+        STATUS(BASE_URI + ADMIN_STATUS, HttpMethod.GET, Response.Status.OK),
 
         //Type operations
         CREATE_TYPE(BASE_URI + TYPES, HttpMethod.POST, Response.Status.CREATED),

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/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
index 6e1fbe2..943301b 100644
--- a/client/src/test/java/org/apache/atlas/AtlasClientTest.java
+++ b/client/src/test/java/org/apache/atlas/AtlasClientTest.java
@@ -28,6 +28,7 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
 
 public class AtlasClientTest {
@@ -37,7 +38,7 @@ public class AtlasClientTest {
         WebResource webResource = mock(WebResource.class);
         AtlasClient atlasClient = new AtlasClient(webResource);
 
-        WebResource.Builder builder = setupBuilder(webResource);
+        WebResource.Builder builder = setupBuilder(AtlasClient.API.VERSION, webResource);
         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\","
+
@@ -47,9 +48,9 @@ public class AtlasClientTest {
         assertTrue(atlasClient.isServerReady());
     }
 
-    private WebResource.Builder setupBuilder(WebResource webResource) {
+    private WebResource.Builder setupBuilder(AtlasClient.API api, WebResource webResource)
{
         WebResource adminVersionResource = mock(WebResource.class);
-        when(webResource.path(AtlasClient.API.VERSION.getPath())).thenReturn(adminVersionResource);
+        when(webResource.path(api.getPath())).thenReturn(adminVersionResource);
         WebResource.Builder builder = mock(WebResource.Builder.class);
         when(adminVersionResource.accept(AtlasClient.JSON_MEDIA_TYPE)).thenReturn(builder);
         when(builder.type(AtlasClient.JSON_MEDIA_TYPE)).thenReturn(builder);
@@ -60,7 +61,7 @@ public class AtlasClientTest {
     public void shouldReturnFalseIfServerIsNotReady() throws AtlasServiceException {
         WebResource webResource = mock(WebResource.class);
         AtlasClient atlasClient = new AtlasClient(webResource);
-        WebResource.Builder builder = setupBuilder(webResource);
+        WebResource.Builder builder = setupBuilder(AtlasClient.API.VERSION, webResource);
         when(builder.method(AtlasClient.API.VERSION.getMethod(), ClientResponse.class, null)).thenThrow(
                 new ClientHandlerException());
         assertFalse(atlasClient.isServerReady());
@@ -70,7 +71,7 @@ public class AtlasClientTest {
     public void shouldReturnFalseIfServiceIsUnavailable() throws AtlasServiceException {
         WebResource webResource = mock(WebResource.class);
         AtlasClient atlasClient = new AtlasClient(webResource);
-        WebResource.Builder builder = setupBuilder(webResource);
+        WebResource.Builder builder = setupBuilder(AtlasClient.API.VERSION, webResource);
         ClientResponse response = mock(ClientResponse.class);
         when(response.getStatus()).thenReturn(Response.Status.SERVICE_UNAVAILABLE.getStatusCode());
         when(response.getClientResponseStatus()).thenReturn(ClientResponse.Status.SERVICE_UNAVAILABLE);
@@ -84,7 +85,7 @@ public class AtlasClientTest {
     public void shouldThrowErrorIfAnyResponseOtherThanServiceUnavailable() throws AtlasServiceException
{
         WebResource webResource = mock(WebResource.class);
         AtlasClient atlasClient = new AtlasClient(webResource);
-        WebResource.Builder builder = setupBuilder(webResource);
+        WebResource.Builder builder = setupBuilder(AtlasClient.API.VERSION, webResource);
         ClientResponse response = mock(ClientResponse.class);
         when(response.getStatus()).thenReturn(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
         when(response.getClientResponseStatus()).thenReturn(ClientResponse.Status.INTERNAL_SERVER_ERROR);
@@ -94,4 +95,49 @@ public class AtlasClientTest {
         atlasClient.isServerReady();
         fail("Should throw exception");
     }
+    
+    @Test
+    public void shouldGetAdminStatus() throws AtlasServiceException {
+        WebResource webResource = mock(WebResource.class);
+        AtlasClient atlasClient = new AtlasClient(webResource);
+
+        WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, webResource);
+        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, "Active");
+    }
+
+    @Test(expectedExceptions = AtlasServiceException.class)
+    public void shouldReturnStatusAsUnknownOnException() throws AtlasServiceException {
+        WebResource webResource = mock(WebResource.class);
+        AtlasClient atlasClient = new AtlasClient(webResource);
+
+        WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, webResource);
+        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
{
+        WebResource webResource = mock(WebResource.class);
+        AtlasClient atlasClient = new AtlasClient(webResource);
+
+        WebResource.Builder builder = setupBuilder(AtlasClient.API.STATUS, webResource);
+        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);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/common/src/main/java/org/apache/atlas/AtlasConstants.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/atlas/AtlasConstants.java b/common/src/main/java/org/apache/atlas/AtlasConstants.java
index 950ed6b..cb46316 100644
--- a/common/src/main/java/org/apache/atlas/AtlasConstants.java
+++ b/common/src/main/java/org/apache/atlas/AtlasConstants.java
@@ -30,4 +30,6 @@ public final class AtlasConstants {
     public static final String CLUSTER_NAME_ATTRIBUTE = "clusterName";
     public static final String SYSTEM_PROPERTY_APP_PORT = "atlas.app.port";
     public static final String DEFAULT_APP_PORT_STR = "21000";
+    public static final String ATLAS_REST_ADDRESS_KEY = "atlas.rest.address";
+    public static final String DEFAULT_ATLAS_REST_ADDRESS = "http://localhost:21000";
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/distro/src/bin/atlas_admin.py
----------------------------------------------------------------------
diff --git a/distro/src/bin/atlas_admin.py b/distro/src/bin/atlas_admin.py
new file mode 100644
index 0000000..894e4da
--- /dev/null
+++ b/distro/src/bin/atlas_admin.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+#
+# 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.
+import os
+import sys
+
+import atlas_config as mc
+import atlas_client_cmdline as cmdline
+
+def main():
+
+    conf_dir = cmdline.setup_conf_dir()
+    jvm_opts_list = cmdline.setup_jvm_opts_list(conf_dir, 'atlas_admin.log')
+    atlas_classpath = cmdline.get_atlas_classpath(conf_dir)
+
+    process = mc.java("org.apache.atlas.AtlasAdminClient", sys.argv[1:], atlas_classpath,
jvm_opts_list)
+    return process.wait()
+
+if __name__ == '__main__':
+    try:
+        returncode = main()
+    except Exception as e:
+        print "Exception: %s " % str(e)
+        returncode = -1
+
+    sys.exit(returncode)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/distro/src/bin/atlas_client_cmdline.py
----------------------------------------------------------------------
diff --git a/distro/src/bin/atlas_client_cmdline.py b/distro/src/bin/atlas_client_cmdline.py
new file mode 100644
index 0000000..f109ad3
--- /dev/null
+++ b/distro/src/bin/atlas_client_cmdline.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+
+#
+# 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.
+
+import os
+import atlas_config as mc
+
+ATLAS_COMMAND_OPTS="-Datlas.home=%s"
+ATLAS_LOG_OPTS="-Datlas.log.dir=%s -Datlas.log.file=%s"
+DEFAULT_JVM_OPTS="-Xmx1024m -Dlog4j.configuration=atlas-log4j.xml"
+
+def setup_conf_dir():
+    atlas_home = mc.atlasDir()
+    return mc.dirMustExist(mc.confDir(atlas_home))
+
+def get_atlas_classpath(confdir):
+    atlas_home = mc.atlasDir()
+    web_app_dir = mc.webAppDir(atlas_home)
+    mc.expandWebApp(atlas_home)
+    p = os.pathsep
+    atlas_classpath = confdir + p \
+                      + os.path.join(web_app_dir, "atlas", "WEB-INF", "classes") + p \
+                      + os.path.join(web_app_dir, "atlas", "WEB-INF", "lib", "*") + p \
+                      + os.path.join(atlas_home, "libext", "*")
+    if mc.isCygwin():
+        atlas_classpath = mc.convertCygwinPath(atlas_classpath, True)
+    return atlas_classpath
+
+def setup_jvm_opts_list(confdir, log_name):
+    atlas_home = mc.atlasDir()
+    mc.executeEnvSh(confdir)
+    logdir = mc.dirMustExist(mc.logDir(atlas_home))
+    if mc.isCygwin():
+        # Pathnames that are passed to JVM must be converted to Windows format.
+        jvm_atlas_home = mc.convertCygwinPath(atlas_home)
+        jvm_logdir = mc.convertCygwinPath(logdir)
+    else:
+        jvm_atlas_home = atlas_home
+        jvm_logdir = logdir
+
+    # create sys property for conf dirs
+    jvm_opts_list = (ATLAS_LOG_OPTS % (jvm_logdir, log_name)).split()
+    cmd_opts = (ATLAS_COMMAND_OPTS % jvm_atlas_home)
+    jvm_opts_list.extend(cmd_opts.split())
+    atlas_jvm_opts = os.environ.get(mc.ATLAS_OPTS, DEFAULT_JVM_OPTS)
+    jvm_opts_list.extend(atlas_jvm_opts.split())
+    return jvm_opts_list

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/distro/src/bin/quick_start.py
----------------------------------------------------------------------
diff --git a/distro/src/bin/quick_start.py b/distro/src/bin/quick_start.py
index 1e0ac05..14c8464 100755
--- a/distro/src/bin/quick_start.py
+++ b/distro/src/bin/quick_start.py
@@ -19,46 +19,13 @@ import os
 import sys
 
 import atlas_config as mc
-
-ATLAS_LOG_OPTS="-Datlas.log.dir=%s -Datlas.log.file=quick_start.log"
-ATLAS_COMMAND_OPTS="-Datlas.home=%s"
-DEFAULT_JVM_OPTS="-Xmx1024m -Dlog4j.configuration=atlas-log4j.xml"
+import atlas_client_cmdline as cmdline
 
 def main():
 
-    atlas_home = mc.atlasDir()
-    confdir = mc.dirMustExist(mc.confDir(atlas_home))
-    mc.executeEnvSh(confdir)
-    logdir = mc.dirMustExist(mc.logDir(atlas_home))
-    if mc.isCygwin():
-        # Pathnames that are passed to JVM must be converted to Windows format.
-        jvm_atlas_home = mc.convertCygwinPath(atlas_home)
-        jvm_logdir = mc.convertCygwinPath(logdir)
-    else:
-        jvm_atlas_home = atlas_home
-        jvm_logdir = logdir
-
-    #create sys property for conf dirs
-    jvm_opts_list = (ATLAS_LOG_OPTS % jvm_logdir).split()
-
-    cmd_opts = (ATLAS_COMMAND_OPTS % jvm_atlas_home)
-    jvm_opts_list.extend(cmd_opts.split())
-
-    default_jvm_opts = DEFAULT_JVM_OPTS
-    atlas_jvm_opts = os.environ.get(mc.ATLAS_OPTS, default_jvm_opts)
-    jvm_opts_list.extend(atlas_jvm_opts.split())
-
-    #expand web app dir
-    web_app_dir = mc.webAppDir(atlas_home)
-    mc.expandWebApp(atlas_home)
-
-    p = os.pathsep
-    atlas_classpath = confdir + p \
-                       + os.path.join(web_app_dir, "atlas", "WEB-INF", "classes" ) + p \
-                       + os.path.join(web_app_dir, "atlas", "WEB-INF", "lib", "*" )  + p
\
-                       + os.path.join(atlas_home, "libext", "*")
-    if mc.isCygwin():
-        atlas_classpath = mc.convertCygwinPath(atlas_classpath, True)
+    conf_dir = cmdline.setup_conf_dir()
+    jvm_opts_list = cmdline.setup_jvm_opts_list(conf_dir, 'quick_start.log')
+    atlas_classpath = cmdline.get_atlas_classpath(conf_dir)
 
     process = mc.java("org.apache.atlas.examples.QuickStart", sys.argv[1:], atlas_classpath,
jvm_opts_list)
     return process.wait()

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/distro/src/conf/atlas-application.properties
----------------------------------------------------------------------
diff --git a/distro/src/conf/atlas-application.properties b/distro/src/conf/atlas-application.properties
index 00c5d5a..29df5b3 100755
--- a/distro/src/conf/atlas-application.properties
+++ b/distro/src/conf/atlas-application.properties
@@ -99,9 +99,10 @@ atlas.rest.address=http://localhost:21000
 
 #########  High Availability Configuration ########
 atlas.server.ha.enabled=false
-atlas.server.ids=id1
-atlas.server.address.id1=localhost:21000
-atlas.server.ha.zookeeper.connect=localhost:2181
-atlas.server.ha.zookeeper.retry.sleeptime.ms=1000
-atlas.server.ha.zookeeper.num.retries=3
-atlas.server.ha.zookeeper.session.timeout.ms=20000
\ No newline at end of file
+#### Enabled the configs below as per need if HA is enabled #####
+#atlas.server.ids=id1
+#atlas.server.address.id1=localhost:21000
+#atlas.server.ha.zookeeper.connect=localhost:2181
+#atlas.server.ha.zookeeper.retry.sleeptime.ms=1000
+#atlas.server.ha.zookeeper.num.retries=3
+#atlas.server.ha.zookeeper.session.timeout.ms=20000

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index 87e39e6..5d3bea0 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -13,6 +13,7 @@ ATLAS-409 Atlas will not import avro tables with schema read from a file
(dosset
 ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via
shwethags)
 
 ALL CHANGES:
+ATLAS-513 Admin support for HA (yhemanth via sumasai)
 ATLAS-511 Ability to run multiple instances of Atlas Server with automatic failover to one
active server (yhemanth via shwethags)
 ATLAS-577 Integrate entity audit with DefaultMetadataService (shwethags)
 ATLAS-588 import-hive.sh fails while importing partitions for a non-partitioned table (sumasai
via shwethags)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/typesystem/src/main/resources/atlas-application.properties
----------------------------------------------------------------------
diff --git a/typesystem/src/main/resources/atlas-application.properties b/typesystem/src/main/resources/atlas-application.properties
index f753785..a343a20 100644
--- a/typesystem/src/main/resources/atlas-application.properties
+++ b/typesystem/src/main/resources/atlas-application.properties
@@ -90,5 +90,5 @@ hbase.security.authentication=simple
 atlas.hook.falcon.synchronous=true
 #########  High Availability Configuration ########
 atlas.server.ha.enabled=false
-atlas.server.ids=id1
-atlas.server.address.id1=localhost:21000
+#atlas.server.ids=id1
+#atlas.server.address.id1=localhost:21000

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/webapp/src/main/java/org/apache/atlas/web/filters/ActiveServerFilter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/filters/ActiveServerFilter.java b/webapp/src/main/java/org/apache/atlas/web/filters/ActiveServerFilter.java
index 49ab1ba..1ff8000 100644
--- a/webapp/src/main/java/org/apache/atlas/web/filters/ActiveServerFilter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/filters/ActiveServerFilter.java
@@ -77,7 +77,11 @@ public class ActiveServerFilter implements Filter {
     @Override
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                          FilterChain filterChain) throws IOException, ServletException {
-        if (isInstanceActive()) {
+        if (isFilteredURI(servletRequest)) {
+            LOG.debug("Is a filtered URI: {}. Passing request downstream.",
+                    ((HttpServletRequest)servletRequest).getRequestURI());
+            filterChain.doFilter(servletRequest, servletResponse);
+        } else if (isInstanceActive()) {
             LOG.debug("Active. Passing request downstream");
             filterChain.doFilter(servletRequest, servletResponse);
         } else if (serviceState.isInstanceInTransition()) {
@@ -97,6 +101,12 @@ public class ActiveServerFilter implements Filter {
         }
     }
 
+    private boolean isFilteredURI(ServletRequest servletRequest) {
+        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+        String requestURI = httpServletRequest.getRequestURI();
+        return requestURI.contains("/admin/");
+    }
+
     boolean isInstanceActive() {
         return serviceState.getState() == ServiceState.ServiceStateValue.ACTIVE;
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
index 38a4938..6068007 100755
--- a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
@@ -18,6 +18,8 @@
 
 package org.apache.atlas.web.resources;
 
+import com.google.inject.Inject;
+import org.apache.atlas.web.service.ServiceState;
 import org.apache.atlas.web.util.Servlets;
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
@@ -41,6 +43,12 @@ import javax.ws.rs.core.Response;
 public class AdminResource {
 
     private Response version;
+    private ServiceState serviceState;
+
+    @Inject
+    public AdminResource(ServiceState serviceState) {
+        this.serviceState = serviceState;
+    }
 
     /**
      * Fetches the thread stack dump for this application.
@@ -98,4 +106,18 @@ public class AdminResource {
 
         return version;
     }
+
+    @GET
+    @Path("status")
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public Response getStatus() {
+        JSONObject responseData = new JSONObject();
+        try {
+            responseData.put("Status", serviceState.getState().toString());
+            Response response = Response.ok(responseData).build();
+            return response;
+        } catch (JSONException e) {
+            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/webapp/src/test/java/org/apache/atlas/web/filters/ActiveServerFilterTest.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/atlas/web/filters/ActiveServerFilterTest.java
b/webapp/src/test/java/org/apache/atlas/web/filters/ActiveServerFilterTest.java
index c6962fa..b3ec8de 100644
--- a/webapp/src/test/java/org/apache/atlas/web/filters/ActiveServerFilterTest.java
+++ b/webapp/src/test/java/org/apache/atlas/web/filters/ActiveServerFilterTest.java
@@ -34,6 +34,7 @@ import javax.ws.rs.HttpMethod;
 import java.io.IOException;
 
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
@@ -64,6 +65,8 @@ public class ActiveServerFilterTest {
     @Test
     public void testShouldPassThroughRequestsIfActive() throws IOException, ServletException
{
         when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.ACTIVE);
+        when(servletRequest.getRequestURI()).thenReturn("api/atlas/types");
+
         ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
 
         activeServerFilter.doFilter(servletRequest, servletResponse, filterChain);
@@ -74,6 +77,8 @@ public class ActiveServerFilterTest {
     @Test
     public void testShouldFailIfCannotRetrieveActiveServerAddress() throws IOException, ServletException
{
         when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
+        when(servletRequest.getRequestURI()).thenReturn("api/atlas/types");
+
         ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
 
         when(activeInstanceState.getActiveServerAddress()).thenReturn(null);
@@ -86,6 +91,8 @@ public class ActiveServerFilterTest {
     @Test
     public void testShouldRedirectRequestToActiveServerAddress() throws IOException, ServletException
{
         when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
+        when(servletRequest.getRequestURI()).thenReturn("api/atlas/types");
+
         ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
 
         when(activeInstanceState.getActiveServerAddress()).thenReturn(ACTIVE_SERVER_ADDRESS);
@@ -100,6 +107,8 @@ public class ActiveServerFilterTest {
     @Test
     public void testRedirectedRequestShouldContainQueryParameters() throws IOException, ServletException
{
         when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
+        when(servletRequest.getRequestURI()).thenReturn("api/atlas/types");
+
         ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
 
         when(activeInstanceState.getActiveServerAddress()).thenReturn(ACTIVE_SERVER_ADDRESS);
@@ -116,6 +125,8 @@ public class ActiveServerFilterTest {
     @Test
     public void testShouldRedirectPOSTRequest() throws IOException, ServletException {
         when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
+        when(servletRequest.getRequestURI()).thenReturn("api/atlas/types");
+
         ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
 
         when(activeInstanceState.getActiveServerAddress()).thenReturn(ACTIVE_SERVER_ADDRESS);
@@ -131,6 +142,8 @@ public class ActiveServerFilterTest {
     @Test
     public void testShouldRedirectPUTRequest() throws IOException, ServletException {
         when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
+        when(servletRequest.getRequestURI()).thenReturn("api/atlas/types");
+
         ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
 
         when(activeInstanceState.getActiveServerAddress()).thenReturn(ACTIVE_SERVER_ADDRESS);
@@ -146,6 +159,8 @@ public class ActiveServerFilterTest {
     @Test
     public void testShouldRedirectDELETERequest() throws IOException, ServletException {
         when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
+        when(servletRequest.getRequestURI()).thenReturn("api/atlas/types");
+
         ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
 
         when(activeInstanceState.getActiveServerAddress()).thenReturn(ACTIVE_SERVER_ADDRESS);
@@ -163,10 +178,26 @@ public class ActiveServerFilterTest {
     @Test
     public void testShouldReturnServiceUnavailableIfStateBecomingActive() throws IOException,
ServletException {
         when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.BECOMING_ACTIVE);
+        when(servletRequest.getRequestURI()).thenReturn("api/atlas/types");
+
         ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
 
         activeServerFilter.doFilter(servletRequest, servletResponse, filterChain);
 
         verify(servletResponse).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
     }
+
+    @Test
+    public void testShouldNotRedirectAdminAPIs() throws IOException, ServletException {
+        when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
+        when(servletRequest.getMethod()).thenReturn(HttpMethod.GET);
+        when(servletRequest.getRequestURI()).
+                thenReturn("api/atlas/admin/asmasn"); // any Admin URI is fine.
+
+        ActiveServerFilter activeServerFilter = new ActiveServerFilter(activeInstanceState,
serviceState);
+        activeServerFilter.doFilter(servletRequest, servletResponse, filterChain);
+
+        verify(filterChain).doFilter(servletRequest, servletResponse);
+        verifyZeroInteractions(activeInstanceState);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fc20719/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java b/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
new file mode 100644
index 0000000..eb2b2f6
--- /dev/null
+++ b/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
@@ -0,0 +1,70 @@
+/**
+ * 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.web.resources;
+
+import org.apache.atlas.web.service.ServiceState;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+
+public class AdminResourceTest {
+
+    @Mock
+    private ServiceState serviceState;
+
+    @BeforeMethod
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testStatusOfActiveServerIsReturned() throws JSONException {
+
+        when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.ACTIVE);
+
+        AdminResource adminResource = new AdminResource(serviceState);
+        Response response = adminResource.getStatus();
+        assertEquals(response.getStatus(), HttpServletResponse.SC_OK);
+        JSONObject entity = (JSONObject) response.getEntity();
+        assertEquals(entity.get("Status"), "ACTIVE");
+    }
+
+    @Test
+    public void testResourceGetsValueFromServiceState() throws JSONException {
+        when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
+
+        AdminResource adminResource = new AdminResource(serviceState);
+        Response response = adminResource.getStatus();
+
+        verify(serviceState).getState();
+        JSONObject entity = (JSONObject) response.getEntity();
+        assertEquals(entity.get("Status"), "PASSIVE");
+
+    }
+}
\ No newline at end of file



Mime
View raw message