Author: mahadev
Date: Mon Apr 15 07:23:10 2013
New Revision: 1467879
URL: http://svn.apache.org/r1467879
Log:
AMBARI-1769. Python REST client to invoke REST calls. (Subin M via mahadev)
Added:
incubator/ambari/trunk/ambari-client/
incubator/ambari/trunk/ambari-client/pom.xml
incubator/ambari/trunk/ambari-client/src/
incubator/ambari/trunk/ambari-client/src/examples/
incubator/ambari/trunk/ambari-client/src/examples/example.py
incubator/ambari/trunk/ambari-client/src/main/
incubator/ambari/trunk/ambari-client/src/main/python/
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/ambari_api.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_client.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_utils.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/base_model.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/cluster.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/paths.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/service.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/utils.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/clusters.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/services.py
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/rest_resource.py
incubator/ambari/trunk/ambari-client/src/main/python/setup.py
incubator/ambari/trunk/ambari-client/src/packages/
incubator/ambari/trunk/ambari-client/src/packages/tarball/
incubator/ambari/trunk/ambari-client/src/packages/tarball/all.xml
incubator/ambari/trunk/ambari-client/src/test/
incubator/ambari/trunk/ambari-client/src/test/python/
incubator/ambari/trunk/ambari-client/src/test/python/unitTests.py
Modified:
incubator/ambari/trunk/CHANGES.txt
Modified: incubator/ambari/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1467879&r1=1467878&r2=1467879&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Mon Apr 15 07:23:10 2013
@@ -1466,6 +1466,8 @@ AMBARI-1.2.0 branch:
AMBARI-1202. Unncessary use of xml tree python library in ambari-server
setup. Its not being used. (Siddharth Wagle via mahadev)
+ AMBARI-1769. Python REST client to invoke REST calls. (Subin M via mahadev)
+
IMPROVEMENTS
BUG FIXES
Added: incubator/ambari/trunk/ambari-client/pom.xml
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/pom.xml?rev=1467879&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-client/pom.xml (added)
+++ incubator/ambari/trunk/ambari-client/pom.xml Mon Apr 15 07:23:10 2013
@@ -0,0 +1,169 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <!--
+ 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.
+-->
+ <parent>
+ <groupId>org.apache.ambari</groupId>
+ <artifactId>ambari-project</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <relativePath>../ambari-project</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.ambari</groupId>
+ <artifactId>ambari-client</artifactId>
+ <packaging>pom</packaging>
+ <version>1.3.0-SNAPSHOT</version>
+ <name>Ambari client</name>
+ <description>Ambari Python client</description>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <final.name>${project.artifactId}-${project.version}</final.name>
+ <package.release>1</package.release>
+ <package.prefix>/usr</package.prefix>
+ <package.log.dir>/var/log/ambari-client</package.log.dir>
+ <package.pid.dir>/var/run/ambari-client</package.pid.dir>
+ <skipTests>false</skipTests>
+ <install.dir>/usr/lib/python2.6/site-packages/ambari_client</install.dir>
+ <lib.dir>/usr/lib/ambari-client/lib</lib.dir>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ <descriptors>
+ <descriptor>src/packages/tarball/all.xml</descriptor>
+ </descriptors>
+ </configuration>
+ <executions>
+ <execution>
+ <id>build-tarball</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2</version>
+ <executions>
+ <execution>
+ <configuration>
+ <executable>python2.6</executable>
+ <workingDirectory>src/test/python</workingDirectory>
+ <arguments>
+ <argument>unitTests.py</argument>
+ </arguments>
+ <environmentVariables>
+
<PYTHONPATH>${project.basedir}/../ambari-common/src/test/python:${project.basedir}/src/main/python/ambari_client:$PYTHONPATH</PYTHONPATH>
+ </environmentVariables>
+ <skip>${skipTests}</skip>
+ </configuration>
+ <id>python-test</id>
+ <phase>test</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </execution>
+ <execution>
+ <configuration>
+ <executable>python2.6</executable>
+
<workingDirectory>target/ambari-client-${project.version}</workingDirectory>
+ <arguments>
+
<argument>${project.basedir}/src/main/python/setup.py</argument>
+ <argument>clean</argument>
+ <argument>bdist_dumb</argument>
+ </arguments>
+ <environmentVariables>
+
<PYTHONPATH>target/ambari-client-${project.version}:$PYTHONPATH</PYTHONPATH>
+ </environmentVariables>
+ </configuration>
+ <id>python-package</id>
+ <phase>package</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>rpm-maven-plugin</artifactId>
+ <version>2.1-alpha-2</version>
+ <executions>
+ <execution>
+ <phase>none</phase>
+ <goals>
+ <goal>rpm</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <copyright>2012, Apache Software Foundation</copyright>
+ <group>Development</group>
+ <description>Maven Recipe: RPM Package.</description>
+ <requires>
+ <require>openssl</require>
+ <require>zlib</require>
+ <require>${python.ver}</require>
+ </requires>
+ <needarch>x86_64</needarch>
+ <autoRequires>false</autoRequires>
+ <mappings>
+ <mapping>
+ <directory>${install.dir}</directory>
+ <sources>
+ <source>
+
<location>${project.build.directory}/${project.artifactId}-${project.version}/ambari_client</location>
+ </source>
+ </sources>
+ </mapping>
+ <!-- -->
+ </mappings>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>src/examples/*</exclude>
+ <exclude>src/test/python/dummy*.txt</exclude>
+ <exclude>src/main/python/ambari_client/imports.txt</exclude>
+ <exclude>src/main/puppet/modules/stdlib/**</exclude>
+ <exclude>**/*.erb</exclude>
+ <exclude>**/*.json</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-external</artifactId>
+ </extension>
+ </extensions>
+ </build>
+</project>
Added: incubator/ambari/trunk/ambari-client/src/examples/example.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/examples/example.py?rev=1467879&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-client/src/examples/example.py (added)
+++ incubator/ambari/trunk/ambari-client/src/examples/example.py Mon Apr 15
07:23:10 2013
@@ -0,0 +1,84 @@
+#
+# 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 logging
+from ambari_client.ambari_api import AmbariClient
+
+
+def main():
+ """
+ This method has few examples on how to use the ambari_client api
+ """
+ path = os.getcwd() ;
+ print path
+ sys.path.append(path)
+
+ logging.basicConfig(filename="ambari_client.log", level=logging.DEBUG
,filemode="w")
+ logging.info("Program started")
+
+
+
+ client = AmbariClient("localhost", 8080, "admin","admin",version=1)
+
+ all_clusters = client.get_all_clusters()
+ print all_clusters
+ print all_clusters.to_json_dict()
+ print"\n"
+
+ cluster = client.get_cluster('test1')
+ print cluster
+ print"\n"
+
+# serviceList = cluster.get_all_services()
+# print serviceList
+# print"\n"
+#
+#
+# for service in serviceList:
+# print str(service.service_name)+" = "+str(service.state)
+# print"\n"
+
+ ganglia = cluster.get_service("GANGLIA")
+ print ganglia.state
+ print"\n"
+
+
+
+# cluster_ref = ganglia.clusterRef
+# print cluster_ref.cluster_name
+# print"\n"
+
+
+ ganglia.stop()
+# ganglia.start()
+
+
+
+########################################################################
+#
+# The "main" entry
+#
+########################################################################
+if __name__ == '__main__':
+ main()
+########################################################################
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/ambari_api.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/ambari_api.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/ambari_api.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/ambari_api.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,98 @@
+#
+# 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 logging
+from ambari_client.http_client import HttpClient
+from ambari_client.resources import clusters
+from ambari_client.rest_resource import RestResource
+
+__docformat__ = "epytext"
+
+LOG = logging.getLogger(__name__)
+
+
+API_VERSION = 1
+
+
+
+
+class AmbariClient(RestResource):
+ """
+ AmbariClient top-level root resources.
+ """
+
+ def __init__(self, host_name, port=None,user_name="admin", password="admin",
+ version=API_VERSION):
+ """
+ Creates a RestResource object.
+
+ @param host_name: The hostname server.
+ @param port: The port of the server.
+ @param user_name: Login name.
+ @param password: Login password.
+ @param version: API version.
+ @return RestResource object referring to the root.
+ """
+
+ self._version = version
+ protocol = "http"
+ if port is None:
+ port = 8080
+ host_url = "%s://%s:%s/api/v%s" %(protocol, host_name, port, version)
+ client = HttpClient(host_url, user_name , password )
+ RestResource.__init__(self, client)
+
+
+
+ @property
+ def version(self):
+ """
+ Returns the API version .
+ """
+ return self._version
+
+
+ def get_all_clusters(self):
+ """
+ Get all clusters.
+ @return: A list of ModelList.
+ """
+ return clusters.get_all_clusters(self)
+
+ def get_cluster(self, cluster_name):
+ """
+ Get a cluster by cluster_name.
+
+ @param cluster_name Cluster cluster_name.
+ @return An ClusterModel.
+ """
+ return clusters.get_cluster(self, cluster_name)
+
+
+
+
+
+def get_root_resource(server_host, server_port=None,username="admin",
password="admin",
+ version=1):
+ """
+ AmbariClient.
+ """
+ return AmbariClient(server_host, server_port, username, password, version)
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_client.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_client.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_client.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_client.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,166 @@
+#
+# 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 logging
+import posixpath
+import sys
+import pycurl
+import cStringIO
+import StringIO
+import pdb
+try:
+ import json
+except ImportError:
+ import simplejson as json
+from ambari_client.http_utils import uri_encoding
+
+__docformat__ = "epytext"
+
+LOG = logging.getLogger(__name__)
+
+
+class HttpClient(object):
+ """
+ Basic HTTP client for rest APIs.
+ """
+ def __init__(self, host_url, user_name , password ):
+ """
+ @param host_url: The base url to the API.
+
+ """
+
+ self._host_url = host_url.rstrip('/')
+ self._headers = { }
+ self.c = pycurl.Curl()
+ if user_name is not None:
+ self.c.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
+ userpass = user_name + ':'
+ if password is not None:
+ userpass += password
+ LOG.debug( "pycurl.USERPWD value = "+str(userpass))
+ self.c.setopt(pycurl.USERPWD, userpass)
+
+
+ def set_headers(self, headers):
+ """
+ Add headers to the request
+ """
+ self._headers = headers
+ return self
+
+ @property
+ def host_url(self):
+ return self._host_url
+
+ def _get_headers(self, headers):
+ res = self._headers.copy()
+ if headers:
+ res.update(headers)
+ return res
+
+ def invoke(self, http_method, path, payload=None, headers=None):
+ """
+ Submit an HTTP request.
+ @param http_method: GET, POST, PUT, DELETE
+ @param path: The path of the resource.
+ @param payload: The payload to attach to the body of the request.
+ @param headers: The headers to set for this request.
+
+ @return: The result of REST request
+ """
+ #pdb.set_trace()
+ LOG.debug ("invoke : http_method = "+str(http_method))
+ # Prepare URL and params
+ url = self._normalize(path)
+ if http_method in ("GET", "DELETE"):
+ if payload is not None:
+ self.logger.warn(
+ "GET http_method does not pass any payload. Path '%s'" % (path,))
+ payload = None
+
+
+ buf = cStringIO.StringIO()
+ self.c.setopt(pycurl.WRITEFUNCTION, buf.write)
+ LOG.debug ("invoke : url = "+str(url))
+ # set http_method
+ if http_method == "GET":
+ self.c.setopt(pycurl.HTTPGET, 1)
+ elif http_method == "HEAD":
+ self.c.setopt(pycurl.HTTPGET, 1)
+ self.c.setopt(pycurl.NOBODY, 1)
+ elif http_method == "POST":
+ self.c.setopt(pycurl.POST, 1)
+ elif http_method == "PUT":
+ self.c.setopt(pycurl.UPLOAD, 1)
+ else:
+ self.c.setopt(pycurl.CUSTOMREQUEST, http_method)
+ iri_to_uri
+ if http_method in ('POST','PUT'):
+ LOG.debug( "data..........."+str(payload))
+ data = json.dumps(payload)
+ data= data.decode('unicode-escape')
+ LOG.debug( data)
+ data = self._to_bytestring(data)
+ LOG.debug( data)
+ content = StringIO.StringIO(data)
+ LOG.debug( content)
+ content_length = len(data)
+ LOG.debug( "content_length........."+str(content_length))
+
+ if http_method == 'POST':
+ self.c.setopt(pycurl.POSTFIELDSIZE, content_length)
+ else:
+ self.c.setopt(pycurl.INFILESIZE, content_length)
+ self.c.setopt(pycurl.READFUNCTION, content.read)
+
+
+ self.c.setopt(self.c.URL, url)
+ headers = self._get_headers(headers)
+ self.c.setopt(pycurl.HTTPHEADER,
+ ["%s: %s" % pair for pair in
sorted(headers.iteritems())])
+
+ LOG.debug ("invoke : pycurl.EFFECTIVE_URL =
"+self.c.getinfo(pycurl.EFFECTIVE_URL))
+ try:
+ self.c.perform()
+ except Exception, ex:
+ LOG.debug (sys.stderr, str(ex))
+ raise ex
+ contents_type= self.c.getinfo(pycurl.CONTENT_TYPE)
+ LOG.debug ("invoke : pycurl.CONTENT_TYPE = "+contents_type)
+ code = self.c.getinfo(pycurl.RESPONSE_CODE)
+ LOG.debug ("invoke : pycurl.RESPONSE_CODE = "+str(code))
+ response = buf.getvalue()
+ buf.close()
+ LOG.debug ("invoke : COMPLETED ")
+ return response , code , contents_type
+
+ def _to_bytestring(self ,s):
+# if not isinstance(s, basestring):
+# raise TypeError("value should be a str or unicode")
+ if isinstance(s, unicode):
+ return s.encode('utf-8')
+ return s
+
+ def _normalize(self, path):
+ res = self._host_url
+ if path:
+ res += posixpath.normpath('/' + path.lstrip('/'))
+ return uri_encoding(res)
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_utils.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_utils.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_utils.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/http_utils.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,53 @@
+#
+# 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 types
+import urllib
+import urllib2
+
+
+def uri_encoding(url):
+ """
+ Returns an ASCII string version of the URL.
+ """
+ if url is None:
+ return url
+ return urllib.quote(get_utf8_str(url), safe="/#%[]=:;$&()+,!?*@'~")
+
+def get_utf8_str(strr, encoding='utf-8'):
+ """
+ Returns a utf8 ecoded 'str'.
+ """
+ errors='strict'
+ if not isinstance(strr, basestring):
+ try:
+ return str(strr)
+ except UnicodeEncodeError:
+ if isinstance(strr, Exception):
+ return ' '.join([get_utf8_str(arg, encoding) for arg in strr])
+ return unicode(strr).encode(encoding, errors)
+ elif strr and encoding != 'utf-8':
+ return strr.decode('utf-8', errors).encode(encoding, errors)
+ elif isinstance(strr, unicode):
+ return strr.encode(encoding, errors)
+ else:
+ return strr
\ No newline at end of file
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/base_model.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/base_model.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/base_model.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/base_model.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,115 @@
+#
+# 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 sys
+import logging
+import time
+from ambari_client.model.utils import
get_REF_object,get_unicode,getREF_var_name
+
+
+__docformat__ = "epytext"
+
+LOG = logging.getLogger(__name__)
+
+
+class BaseModel(object):
+ """
+ The BaseModel
+
+ RW_ATTR - A list of mutable attributes
+ RO_ATTR - A list of immutable attributes
+ REF_ATTR - A REF attribute
+
+ """
+ RO_ATTR = ( )
+ RW_ATTR = ( )
+ REF_ATTR = ( )
+
+
+ def __init__(self, resource_root, **rw_attrs):
+ #print" ================== base_model\n"
+ #print locals()
+ self._resource_root = resource_root
+ for k, v in rw_attrs.items():
+ if k not in self.RW_ATTR:
+ raise ValueError("Unknown argument '%s' in %s" %
+ (k, self.__class__.__name__))
+ self._setattr(k, v)
+
+ def _get_resource_root(self):
+ return self._resource_root
+
+ def to_json_dict(self):
+ dic = { }
+ for attr in self.RW_ATTR:
+ value = getattr(self, attr)
+ try:
+ value = value.to_json_dict()
+ except Exception:
+ pass
+ dic[attr] = value
+ return dic
+
+ def _setattr(self, k, v):
+ """Set an attribute. """
+ value=v
+ if v and k.endswith("Ref"):
+ cls_name = k[0].upper() + k[1:]
+ cls_name = cls_name[:-3] + "ModelRef"
+ cls=get_REF_object(cls_name)
+ LOG.debug(str(cls_name) +" - "+str(cls))
+ v = get_unicode(v)
+ var_name=getREF_var_name(cls_name)
+ c={str(var_name):str(v)}
+ LOG.debug(c)
+ value = cls(self._get_resource_root(), **c)
+ setattr(self, k, value)
+
+
+
+
+
+
+class ModelList(object):
+ """A list of Model objects"""
+ LIST_KEY = "items"
+
+ def __init__(self, objects):
+ self.objects = objects
+
+ def __str__(self):
+ return "<<ModelList>>[size = %d]) = [%s]" % (
+ len(self.objects),
+ ", ".join([str(item) for item in self.objects]))
+
+ def to_json_dict(self):
+ return { ModelList.LIST_KEY :
+ [ x.to_json_dict() for x in self.objects ] }
+
+ def __len__(self):
+ return self.objects.__len__()
+
+ def __iter__(self):
+ return self.objects.__iter__()
+
+ def __getitem__(self, i):
+ return self.objects.__getitem__(i)
+
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/cluster.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/cluster.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/cluster.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/cluster.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,90 @@
+#
+# 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 logging
+from ambari_client.model.base_model import BaseModel
+from ambari_client.model.paths import CLUSTERS_PATH
+from ambari_client.model import service
+from ambari_client.model.utils import ModelUtils ,retain_self_helper
+
+
+LOG = logging.getLogger(__name__)
+
+
+def get_cluster(resource_root, cluster_name):
+ """
+ Lookup a cluster by cluster_name
+ @param resource_root: The root Resource .
+ @param cluster_name: cluster_name
+ @return: A ClusterModel object
+ """
+ dic = resource_root.get("%s/%s" % (CLUSTERS_PATH, cluster_name))
+ return ModelUtils.create_model(ClusterModel ,dic, resource_root,"Clusters")
+
+def get_all_clusters(root_resource, details=None):
+ """
+ Get all clusters
+ @param root_resource: The root Resource .
+ @return: A list of ClusterModel objects.
+ """
+ dic = root_resource.get(CLUSTERS_PATH)
+ return ModelUtils.get_model_list(ClusterModel, dic, root_resource
,"Clusters")
+
+
+
+
+
+
+class ClusterModel(BaseModel):
+
+ RW_ATTR = ('cluster_name', 'version')
+
+
+ def __init__(self, resource_root, cluster_name, version):
+ retain_self_helper(**locals())
+
+ def __str__(self):
+ return "<<ClusterModel>> = %s; version = %s" % (self.cluster_name,
self.version)
+
+ def _path(self):
+ return "%s/%s" % (CLUSTERS_PATH, self.cluster_name)
+
+ def get_service(self, service_name):
+ """
+ Get a service by service_name.
+ @param service_name: Service service_name
+ @return: A ServiceModel object
+ """
+ return service.get_service(self._get_resource_root(), service_name,
self.cluster_name)
+
+ def get_all_services(self, detail = None):
+ """
+ Get all services in this cluster.
+ @return: A list of ServiceModel objects.
+ """
+ return service.get_all_services(self._get_resource_root(),
self.cluster_name)
+
+
+
+class ClusterModelRef(BaseModel):
+ RW_ATTR = ('cluster_name',)
+ def __init__(self, resource_root, cluster_name = None):
+ retain_self_helper(**locals())
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/paths.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/paths.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/paths.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/paths.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,26 @@
+#
+# 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.
+'''
+
+
+
+'''
+CLUSTERS_PATH = "/clusters"
+SERVICES_PATH = "/clusters/%s/services"
+SERVICE_PATH = "/clusters/%s/services/%s"
+
+
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/service.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/service.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/service.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/service.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,93 @@
+# 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 logging
+
+from ambari_client.model.base_model import BaseModel
+from ambari_client.model.paths import SERVICES_PATH ,SERVICE_PATH
+from ambari_client.model.utils import ModelUtils ,retain_self_helper
+
+LOG = logging.getLogger(__name__)
+
+
+def get_all_services(resource_root, cluster_name="default"):
+ path = SERVICES_PATH % (cluster_name,)
+ path = path +'?fields=*'
+ dic = resource_root.get(path)
+ return ModelUtils.get_model_list(ServiceModel, dic, resource_root
,"ServiceInfo")
+
+
+def get_service(resource_root, service_name, cluster_name="default"):
+ path = "%s/%s" % (SERVICES_PATH % (cluster_name,), service_name)
+ dic = resource_root.get(path)
+ return ModelUtils.create_model(ServiceModel ,dic,
resource_root,"ServiceInfo")
+
+
+
+
+
+class ServiceModel(BaseModel):
+ RO_ATTR = ('state', 'cluster_name')
+ RW_ATTR = ('service_name', 'type')
+ REF_ATTR = ('cluster_name',)
+
+ def __init__(self, resource_root, service_name):
+ #BaseModel.__init__(self, **locals())
+ retain_self_helper(**locals())
+
+ def __str__(self):
+ return "<<ServiceModel>> = %s (cluster_name = %s)" % (self.service_name,
self._get_cluster_name())
+
+ def _get_cluster_name(self):
+ if self.clusterRef:
+ return self.clusterRef.cluster_name
+ return None
+
+ def _path(self):
+ """
+ Return the API path for this service.
+ """
+ if self._get_cluster_name():
+ return SERVICE_PATH % (self._get_cluster_name(), self.service_name)
+ else:
+ return ''
+
+
+ def _action(self, data=None):
+ path = self._path()
+ self._get_resource_root().put(path, payload=data)
+ return None
+
+
+ def start(self):
+ """
+ Start a service.
+ """
+ data={"ServiceInfo": {"state": "STARTED"}}
+ return self._action(data)
+
+ def stop(self):
+ """
+ Stop a service.
+ """
+ data={"ServiceInfo": {"state": "INSTALLED"}}
+ return self._action(data)
+
+
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/utils.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/utils.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/utils.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/model/utils.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,135 @@
+#
+# 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 logging
+import sys
+
+LOG = logging.getLogger(__name__)
+
+ref_dic = {"cluster_name":"clusterRef"}
+ref_class_dic = {"ClusterModelRef":"cluster_name"}
+ref_pkg_dic={"ClusterModelRef":"ambari_client.model.cluster"}
+
+class ModelUtils(object):
+
+ @staticmethod
+ def get_model_list(member_cls, dic, resource_root , RESOURCE_KEY_WORD):
+ #print locals()
+ from ambari_client.model.base_model import ModelList
+ json_list = dic[ModelList.LIST_KEY]
+ LOG.debug ("get_model_list : getting the "+str(ModelList.LIST_KEY)+ "
value---> \n\t"+str(json_list) )
+
+ if isinstance(json_list, list):
+ json_list_new = [ x.get(RESOURCE_KEY_WORD) for x in json_list]
+
+ LOG.debug ("get_model_list: creating a array for
"+str(RESOURCE_KEY_WORD)+" value---> \n\t"+str(json_list_new))
+ objects = [ ModelUtils.create_model(member_cls,x, resource_root
,RESOURCE_KEY_WORD) for x in json_list_new ]
+ LOG.debug (objects)
+ return ModelList(objects)
+
+ @staticmethod
+ def create_model(member_cls, dic, resource_root,RESOURCE_KEY_WORD):
+ #print locals()
+ rw_dict = { }
+ LOG.debug (" create_model : dic = "+str(dic))
+ if isinstance(dic, dict) and dic.has_key(RESOURCE_KEY_WORD):
+ dic=dic[RESOURCE_KEY_WORD]
+ LOG.debug (" dic.items() 2 = "+str(dic.items()))
+ for k, v in dic.items():
+ LOG.debug (k)
+ LOG.debug (v)
+ if k in member_cls.RW_ATTR:
+ LOG.debug (k + " is there in RW_ATTR")
+ rw_dict[k] = v
+ del dic[k]
+
+ rw_dict = get_unicode_kw(rw_dict)
+ obj = member_cls(resource_root, **rw_dict)
+
+
+ for attr in member_cls.RO_ATTR:
+ obj._setattr(attr, None)
+
+
+ for k, v in dic.items():
+ if k in member_cls.RO_ATTR:
+ obj._setattr(k, v)
+ else:
+ LOG.debug("Unexpected attribute '%s' in %s json" %(k,
member_cls.__name__))
+
+ for attr in member_cls.REF_ATTR:
+ LOG.debug(attr)
+ obj._setattr(getREF_class_name(attr), None)
+
+
+ for k, v in dic.items():
+ if k in member_cls.REF_ATTR:
+ obj._setattr(getREF_class_name(k), v)
+ else:
+ LOG.debug("Unexpected attribute '%s' in %s json" %(k,
member_cls.__name__))
+
+ return obj
+
+
+
+
+def getREF_class_name( REF_name):
+ if ref_dic.has_key(REF_name):
+ return ref_dic[str(REF_name)]
+ else:
+ return None
+
+
+def getREF_var_name( REF_name):
+ if ref_class_dic.has_key(REF_name):
+ return ref_class_dic[str(REF_name)]
+ else:
+ return None
+
+def get_REF_object(ref_class_name):
+ """
+ Gets the Ref object based on class_name
+ """
+ class_ref=getattr(sys.modules[ref_pkg_dic[ref_class_name]], ref_class_name)
+ LOG.debug( class_ref )
+ return class_ref
+
+def get_unicode( v):
+ import unicodedata
+ if v:
+ v = unicodedata.normalize('NFKD', v).encode('ascii', 'ignore')
+ LOG.debug( v )
+ return v
+
+def retain_self_helper(self=None, **kwargs):
+ #print" ================== retain_self_helper\n"
+ #print locals()
+ from ambari_client.model.base_model import BaseModel
+ BaseModel.__init__(self, **kwargs)
+
+def get_unicode_kw(dic):
+ """
+ We use unicode strings as keys in kwargs.
+ """
+ res = { }
+ for k, v in dic.iteritems():
+ res[str(k)] = v
+ return res
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/clusters.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/clusters.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/clusters.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/clusters.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,44 @@
+#
+# 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.
+'''
+
+
+
+'''
+
+from ambari_client.model import cluster
+__docformat__ = "epytext"
+
+
+def get_cluster(resource_root, cluster_name):
+ """
+ Get a cluster by cluster_name
+ @param resource_root: The root Resource.
+ @param cluster_name: Cluster cluster_name
+ @return: ClusterModel object
+ """
+ return cluster.get_cluster(resource_root, cluster_name)
+
+
+
+def get_all_clusters(root_resource):
+ """
+ Get all clusters in Ambari.
+ @param root_resource: The root Resource object.
+ @return: A list of ClusterModel objects in ModelList.
+ """
+ return cluster.get_all_clusters(root_resource)
\ No newline at end of file
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/services.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/services.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/services.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/resources/services.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,45 @@
+# 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.
+'''
+
+
+
+'''
+
+from ambari_client.model import service
+__docformat__ = "epytext"
+
+
+def get_service(resource_root, service_name, cluster_name="default"):
+ """
+ Get a service by service_name
+ @param resource_root: The root Resource .
+ @param service_name: Service service_name.
+ @param cluster_name: Cluster service_name.
+ @return: ServiceModel object.
+ """
+ return service.get_service(resource_root, service_name, cluster_name)
+
+
+
+def get_all_services(resource_root, cluster_name="default"):
+ """
+ Get all services.
+ @param resource_root: The root Resource.
+ @param cluster_name: Cluster name.
+ @return: A list of ServiceModel objects in ModelList.
+ """
+ return service.get_all_services(resource_root, cluster_name)
\ No newline at end of file
Added:
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/rest_resource.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/rest_resource.py?rev=1467879&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/rest_resource.py
(added)
+++
incubator/ambari/trunk/ambari-client/src/main/python/ambari_client/rest_resource.py
Mon Apr 15 07:23:10 2013
@@ -0,0 +1,101 @@
+#
+# 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.
+'''
+
+
+
+'''
+try:
+ import json
+except ImportError:
+ import simplejson as json
+import logging
+import posixpath
+
+LOG = logging.getLogger(__name__)
+
+
+class RestResource(object):
+ """
+ RestResource wrapper.
+ """
+ def __init__(self, client, path=""):
+ """
+ @param client: A Client object.
+ @param path: The relative path of the resource.
+ """
+ self._client = client
+ self._path = path.strip('/')
+
+ @property
+ def base_url(self):
+ return self._client.base_url
+
+ def _join_uri(self, relpath):
+ if relpath is None:
+ return self._path
+ return self._path + posixpath.normpath('/' + relpath)
+
+ def _set_headers(self, content_type=None):
+ if content_type:
+ return { 'Content-Type': content_type }
+ return None
+
+ def invoke(self, http_method, url_path=None, payload=None, headers=None):
+ """
+ Invoke an API http_method.
+ """
+ path = self._join_uri(url_path)
+ resp ,code , content = self._client.invoke(http_method,
path,payload=payload,
+ headers=headers)
+
+ LOG.debug ("RESPONSE from the REST request >>>>>>> \n"+str(resp) )
+ LOG.debug ("\n===========================================================")
+ if not resp and code!=200:
+ raise Exception("Command '%s %s' failed" %(http_method, path))
+ try:
+ if code==200 and not resp:
+ return {}
+ json_dict = json.loads(resp)
+ return json_dict
+ except Exception, ex:
+ LOG.error('JSON decode error: %s' % (resp,))
+ raise ex
+
+
+
+ def get(self, path=None):
+ """
+ Invoke the GET method .
+ @param path: resource path
+ @return: A dictionary of the REST result.
+ """
+ return self.invoke("GET", path)
+
+
+ def put(self, path=None, payload=None, content_type=None):
+ """
+ Invoke the PUT method on a resource.
+ @param path: resource path
+ @param payload: Body of the request.
+ @param content_type:
+ @return: A dictionary of the REST result.
+ """
+ return self.invoke("PUT", path, payload,self._set_headers(content_type))
+
+
+
Added: incubator/ambari/trunk/ambari-client/src/main/python/setup.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/main/python/setup.py?rev=1467879&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-client/src/main/python/setup.py (added)
+++ incubator/ambari/trunk/ambari-client/src/main/python/setup.py Mon Apr 15
07:23:10 2013
@@ -0,0 +1,39 @@
+# 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.
+
+
+from setuptools import setup, find_packages
+
+from sys import version_info, platform
+
+if version_info[:2] > (2, 5):
+ install_requires = []
+else:
+ install_requires = ['simplejson >= 2.0.0']
+
+# Python 2.6 and below requires argparse
+if version_info[:2] < (2, 7):
+ install_requires += ['argparse']
+
+setup(
+ name = 'ambari_client',
+ author_email = "[email protected]",
+ version = "1.0.3-SNAPSHOT",
+ packages = ['ambari_client'],
+ install_requires = install_requires,
+ description = 'Ambari python REST API client',
+ license = 'Apache License 2.0'
+)
Added: incubator/ambari/trunk/ambari-client/src/packages/tarball/all.xml
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/packages/tarball/all.xml?rev=1467879&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-client/src/packages/tarball/all.xml (added)
+++ incubator/ambari/trunk/ambari-client/src/packages/tarball/all.xml Mon Apr
15 07:23:10 2013
@@ -0,0 +1,34 @@
+<?xml version="1.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.
+-->
+<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.1"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.1
http://maven.apache.org/xsd/assembly-1.1.1.xsd">
+ <!--This 'all' id is not appended to the produced bundle because we do this:
+
http://maven.apache.org/plugins/maven-assembly-plugin/faq.html#required-classifiers
+ -->
+ <formats>
+ <format>dir</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <fileSets>
+ <fileSet>
+ <directory>src/main/python</directory>
+ <outputDirectory>/</outputDirectory>
+ </fileSet>
+ </fileSets>
+</assembly>
Added: incubator/ambari/trunk/ambari-client/src/test/python/unitTests.py
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-client/src/test/python/unitTests.py?rev=1467879&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-client/src/test/python/unitTests.py (added)
+++ incubator/ambari/trunk/ambari-client/src/test/python/unitTests.py Mon Apr
15 07:23:10 2013
@@ -0,0 +1,114 @@
+#!/usr/bin/env python2.6
+
+'''
+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 unittest
+import doctest
+from os.path import dirname, split, isdir
+import logging.handlers
+import logging
+
+LOG_FILE_NAME='tests.log'
+SELECTED_PREFIX = "_"
+PY_EXT='.py'
+
+class TestAgent(unittest.TestSuite):
+ def run(self, result):
+ run = unittest.TestSuite.run
+ run(self, result)
+ return result
+
+
+def parent_dir(path):
+ if isdir(path):
+ if path.endswith(os.sep):
+ path = os.path.dirname(path)
+ parent_dir = os.path.dirname(path)
+ else:
+ parent_dir = os.path.dirname(os.path.dirname(path))
+
+ return parent_dir
+
+
+def all_tests_suite():
+
+
+ src_dir = os.getcwd()
+ files_list=os.listdir(src_dir)
+ tests_list = []
+
+ logger.info('------------------------TESTS
LIST:-------------------------------------')
+ # If test with special name exists, run only this test
+ selected_test = None
+ for file_name in files_list:
+ if file_name.endswith(PY_EXT) and not file_name == __file__ and
file_name.startswith(SELECTED_PREFIX):
+ logger.info("Running only selected test " + str(file_name))
+ selected_test = file_name
+ if selected_test is not None:
+ tests_list.append(selected_test.replace(PY_EXT, ''))
+ else:
+ for file_name in files_list:
+ if file_name.endswith(PY_EXT) and not file_name == __file__:
+ logger.info(file_name)
+ tests_list.append(file_name.replace(PY_EXT, ''))
+
logger.info('------------------------------------------------------------------------')
+
+ suite = unittest.TestLoader().loadTestsFromNames(tests_list)
+ return TestAgent([suite])
+
+def main():
+
+
logger.info('------------------------------------------------------------------------')
+ logger.info('PYTHON AGENT TESTS')
+
logger.info('------------------------------------------------------------------------')
+ runner = unittest.TextTestRunner(verbosity=2, stream=sys.stdout)
+ suite = all_tests_suite()
+ status = runner.run(suite).wasSuccessful()
+
+ if not status:
+
logger.error('-----------------------------------------------------------------------')
+ logger.error('Python unit tests failed')
+ logger.error('Find detailed logs in ' + path)
+
logger.error('-----------------------------------------------------------------------')
+ exit(1)
+ else:
+
logger.info('------------------------------------------------------------------------')
+ logger.info('Python unit tests finished succesfully')
+
logger.info('------------------------------------------------------------------------')
+
+if __name__ == '__main__':
+ import os
+ import sys
+ import io
+ sys.path.insert(0,
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
+ sys.path.insert(0,
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +
os.sep + 'main' + os.sep + 'python')
+ sys.path.insert(0,
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +
os.sep + 'main' + os.sep + 'python' + os.sep + 'ambari_agent')
+ logger = logging.getLogger()
+ logger.setLevel(logging.INFO)
+ formatter = logging.Formatter("[%(levelname)s] %(message)s")
+ src_dir = os.getcwd()
+ target_dir = parent_dir(parent_dir(parent_dir(src_dir))) + os.sep + 'target'
+ if not os.path.exists(target_dir):
+ os.mkdir(target_dir)
+ path = target_dir + os.sep + LOG_FILE_NAME
+ file=open(path, "w")
+ consoleLog = logging.StreamHandler(file)
+ consoleLog.setFormatter(formatter)
+ logger.addHandler(consoleLog)
+ main()