У нас есть несколько сторонних библиотек Perl для передачи файлов в / из и, кроме всего прочего, для шифрования / дешифрования файлов с использованием PGP. В настоящее время эти библиотеки используют избыточный код и выполняют вышеупомянутые методы, используя system()
и двоичные файлы командной строки.
Я хочу переписать эти библиотеки, используя больше модулей и ООП, где это необходимо. В настоящее время я размышляю над тем, как я хочу настроить основную библиотеку, включая сценарии Perl для использования Net::SFTP
для размещения / получения файлов и Crypt::PGPSimple
для шифрования / дешифрования файлов.
Должен ли библиотечный модуль быть написан на ООП? Имеет ли это смысл? Или следует импортировать (и разрабатывать процедурно) методы по мере необходимости и создавать объекты Net::SFTP
и Crypt::PGPSimple
по мере необходимости? Я просто не уверен, что хочу создать объект Lib и инициализировать SFTP, PGP, Constants и т. Д. В подпункте new
. Я полагаю, что этот тип класса больше похож на класс Java со статическими методами, но должен быть только один объект / соединение SFTP (не уверен, что Net::SFTP
уже позаботился об этом?) И один Crypt::PGPSimple
и т. Д.
Кроме того, возвращаясь к избыточности, эта библиотека также должна иметь родительский элемент, который определяет функции, которые используют многие сторонние библиотеки (FTP, PGP и т. Д.).
Я не ищу определенного ответа, потому что, вероятно, его нет, но, возможно, как другие подходят к дизайну, подобному этому, и что является наиболее "разумным".
Спасибо
Обновление: Добавлен пример кода моего модуля библиотеки ООП, который также использует другие объекты (PGPSimple, SFTP). Дайте мне знать, если вы можете придумать лучший дизайн / реализацию. Еще раз спасибо.
Lib.pm
use Crypt::PGPSimple;
use Net::SFTP;
use File::Copy;
use Log::Log4perl qw(get_logger :levels);
use File::Basename;
my %CONS = (
RECIPIENT => "ClientName";
URL => 'ftp.host.com';
USER => 'user';
PASS => ''; # use subroutine to obfuscate the password
PORT => '22'
HOME_DIR => '/Home';
IN_DIR => '/Incoming';
OUT_DIR => '/Outgoing';
);
my %VARS;
# private member variables
my ($logger);
BEGIN {
%VARS = (
IS_PROD => $L_is_prod ? 1 : 0;
APPS => $ENV{'APPS'};
OUTDIR => $ENV{'OUTDIR'};
TIME_ZONE => $ENV{"TZ"};
);
$logger = get_logger("Lib");
}
sub new {
my ($class, $self) = @_;
$self = {
pgp => _setup_pgp();
sftp => undef; # Don't create SFTP connection until we need it
};
return bless($self, $class);
}
sub _setup_pgp {
my $pgp = Crypt::PGPSimple->new();
$pgp->PgpVersion(6.5.8);
$pgp->PgpExePath("/path/to/pgp-6.5.8");
$pgp->PgpKeyPath("/home/username/.pgp"); # Set this based on environment
$pgp->PublicKey("pubring.pkr");
$pgp->PrivateKey("secring.skr");
$pgp->Password(pp());
$pgp->UserId();
$pgp->PgpTempDir("/tmp/");
$pgp->PgpTimeZone();
$pgp->PgpVerbose(2);
return $pgp;
}
sub _setup_sftp {
# Create SFTP connection
my $sftp;
my ($host, $user, $pass);
$host = $CONS{URL};
$user = $CONS{USER};
$pass = $CONS{PASS};
$sftp = _connect_sftp($host, (user => $user, password => $pass));
return $sftp;
}
sub encrypt {
my ($self, $plain_file) = @_;
my $pgp = $self->{pgp};
$logger->info("Setting \$pgp->PlainTextFile to $plain_file");
$pgp->PlainTextFile($plain_file);
$pgp->PgpFlags("e");
my $result = $pgp->EncryptFile;
if($result != 0) {
$logger->info("Failed to successfully encrypt $plain_file. Error code: " . $pgp->ErrCode() . ", Result: " . $pgp->Result());
}
return $result;
}
sub put {
my $self = shift;
$self->{sftp} = _setup_sftp() if(!defined $self->{sftp});
my $local = $self->{pgp}->EncryptedTextFile();
my $remote = basename($local);
...
$sftp->put($local, $remote)
...
}