%Hadoop Interact with a Hadoop cluster
%   The Hadoop cluster type allows you to perform mapreduce using workers
%   running under the given Hadoop environment.
%
%   parallel.cluster.Hadoop properties:
%      AdditionalPaths                  - A list of paths to be added to the worker MATLAB path
%      AttachedFiles                    - A list of files to be sent to the workers during a mapreduce call
%      AutoAttachFiles                  - Determines whether dependent files will be automatically sent to the workers
%      ClusterMatlabRoot                - Specifies the path to MATLAB for workers to use
%      HadoopConfigurationFile          - An application configuration file to be given to Hadoop
%      HadoopInstallFolder              - The installation of Hadoop on the local machine
%      HadoopProperties                 - A map of name-value property pairs to be given to Hadoop
%      LicenseNumber                    - License number to use with online licensing
%      RequiresOnlineLicensing          - Cluster uses online licensing
%      SparkInstallFolder               - The installation of Spark on the local machine
%      SparkProperties                  - A map of name-value property pairs to be given to Hadoop

%   Copyright 2014-2018 The MathWorks, Inc.

classdef Hadoop < handle & parallel.internal.customattr.CustomGetSet
    properties (PCTGetSet, Transient, PCTConstraint = 'string')
        %HadoopInstallFolder The installation of Hadoop on the local machine
        %   Specifies the path to Hadoop on the local client machine. This will
        %   be the installation of Hadoop used to perform the MapReduce
        %   algorithm.
        HadoopInstallFolder
        
        %HadoopConfigurationFile An application configuration file to be given to Hadoop
        %   Specifies an application configuration file that is passed to
        %   Hadoop.
        HadoopConfigurationFile
        
        %SparkInstallFolder The installation of Spark on the local machine
        %   Specifies the path to Spark on the local client machine. This will
        %   be the installation of Spark used to perform tall expressions
        %   on a Hadoop cluster.
        SparkInstallFolder
    end
    
    properties (PCTGetSet, Transient, SetAccess = immutable)
        %HadoopProperties A map of name-value property pairs to be given to Hadoop
        %   A map of name-value pairs that specify Hadoop properties. These
        %   will be passed directly to Hadoop.
        HadoopProperties;
        
        %SparkProperties A map of name-value property pairs to be given to Hadoop
        %   A map of name-value pairs that specify Spark properties. These
        %   will be passed directly to Spark when evaluating tall expressions.
        SparkProperties;
    end
    
    properties (PCTGetSet, Transient, PCTConstraint = 'string')
        %ClusterMatlabRoot Specifies the path to MATLAB for workers to use
        %   ClusterMatlabRoot specifies the path name to MATLAB for the
        %   cluster to use for starting MATLAB worker processes.
        ClusterMatlabRoot
    end
    
    properties (PCTGetSet, Transient, PCTConstraint = 'logical')
        %RequiresOnlineLicensing Cluster uses online licensing
        %   RequiresOnlineLicensing indicates whether the cluster uses
        %   online licensing.  You must provide your MathWorks account
        %   login information if this value is true.  If you have more than one
        %   MATLAB Parallel Server license associated with your
        %   MathWorks account you will also need to supply the LicenseNumber to
        %   use.
        %
        %   See also parallel.cluster.Hadoop.LicenseNumber
        RequiresOnlineLicensing = false;
    end
    
    properties (PCTGetSet, Transient, PCTConstraint = 'string')
        %LicenseNumber License number to use with online licensing
        %   License number specifies the license number to use on the workers
        %   when the cluster is using online licensing.  This string
        %   must be the same as one of the licenses listed in your MathWorks
        %   account.
        %
        %   LicenseNumber cannot be defined if RequiresOnlineLicensing is
        %   false.
        %
        %   See also parallel.cluster.Hadoop.RequiresOnlineLicensing
        LicenseNumber = '';
    end
    
    properties (PCTGetSet, Transient, PCTConstraint = 'logical')
        %AutoAttachFiles Determines whether dependent files will be automatically sent to the workers
        %   If true the files required to run the job's task functions will be calculated
        %   and sent to the workers at job submission time.
        %   See also parallel.cluster.Hadoop/AttachedFiles, parallel.cluster.Hadoop/AdditionalPaths.
        AutoAttachFiles = true;
    end
    
    properties (PCTGetSet, Transient, PCTConstraint = 'nonemptycellstr')
        %AttachedFiles A list of files to be sent to the workers during a mapreduce call
        %   AttachedFiles can be modified only before the job is submitted.
        AttachedFiles  = {};
        
        %AdditionalPaths A list of paths to be added to the worker MATLAB path
        %   AdditionalPaths can be modified only before the job is submitted.
        AdditionalPaths = {};
    end
    
    properties (SetAccess = immutable, Transient, Hidden)
        Impl;
    end
    
    properties (Access = private, Transient)
        MatlabLogoutListener;
    end

    properties (Hidden, Dependent)
        RequiresMathWorksHostedLicensing
    end

    methods
        function val = get.RequiresMathWorksHostedLicensing(obj)
            val = obj.RequiresOnlineLicensing;
        end
        function set.RequiresMathWorksHostedLicensing(obj, val)
            obj.RequiresOnlineLicensing = val;
        end
    end
    
    methods
        function obj = Hadoop(varargin)
            %Hadoop Create a Hadoop cluster instance
            %   parallel.cluster.Hadoop(p1, v1, p2, v2, ...) builds a generic
            %   cluster with the specified property values. The properties can
            %   include any of the properties of the Hadoop cluster class.
            %
            %   Example:
            %   myCluster = parallel.cluster.Hadoop('HadoopInstallFolder', '/usr/local/hadoop');
            try
                obj.Impl = parallel.internal.hadoop.HadoopCluster;
                % We do the set here so that error messages reference
                % parallel.cluster.Hadoop instead of internal objects.
                [varargin{:}] = convertStringsToChars(varargin{:});
                set(obj, varargin{:});
                obj.Impl.hEnsureHadoopInstallFolderIsSet();
            catch err
                throw(err);
            end
        end
    end
    
    methods (Hidden)
        % Hidden method to forward all property implementations to the impl
        % object.
        function hSetProperty(obj, names, values)
            try
                hSetProperty(obj.Impl, names, values);
                
                % If we have set RequiresOnlineLicensing to true,
                % we need to register a logout listener with the current
                % desktop client (if one has not already been registered)
                if obj.RequiresOnlineLicensing && isempty(obj.MatlabLogoutListener)
                    confirmLogout = true;
                    obj.MatlabLogoutListener = parallel.internal.mwa.addLogoutListener(...
                        'InvalidatingClusters', @obj.onInvalidatingClusters, confirmLogout);
                end
            catch err
                throw(err);
            end
        end
        function values = hGetProperty(obj, names)
            values = hGetProperty(obj.Impl, names);
        end
        hSetPropertyNoCheck(this, name, value)
        
        % This will be true unless the cluster object has been loaded from a mat file.
        function out = hIsHadoopClusterValid( obj )
            out = ~isempty(obj.Impl) && isvalid(obj.Impl);
        end
    end
    
    methods (Access = private)
        function onInvalidatingClusters( obj )
            % If the cluster is using online licensing at the
            % time of logout, invalidate the cluster impl object and this
            % wrapper class for the impl
            if obj.RequiresOnlineLicensing
                obj.Impl.hInvalidate();
                obj.delete();
            end
        end
    end
end
%#ok<*ATUNK>
