Commit 52256599 authored by Steven Murray's avatar Steven Murray
Browse files

Simplified instantiation logic of MediaChangerFacade

parent c624d1b2
......@@ -48,8 +48,7 @@ public:
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
virtual void mountTapeReadOnly(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot) = 0;
virtual void mountTapeReadOnly(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
/**
* Request the CASTOR ACS daemon to mount the specifed tape for read/write
......@@ -58,8 +57,7 @@ public:
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
virtual void mountTapeReadWrite(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot) = 0;
virtual void mountTapeReadWrite(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
/**
* Request the CASTOR ACS daemon to dismount the specifed tape from the tape
......@@ -68,8 +66,7 @@ public:
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
virtual void dismountTape(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot) = 0;
virtual void dismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
/**
* Request the CASTOR ACS daemon to forcefully dismount the specifed tape
......@@ -82,8 +79,7 @@ public:
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
virtual void forceDismountTape(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot) = 0;
virtual void forceDismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
}; // class AcsProxy
......
/*
* The CERN Tape Archive(CTA) project
* Copyright(C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mediachanger/AcsProxyDummy.hpp"
//------------------------------------------------------------------------------
// mountTapeReadOnly
//------------------------------------------------------------------------------
void cta::mediachanger::AcsProxyDummy::mountTapeReadOnly(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot) {
}
//------------------------------------------------------------------------------
// mountTapeForMigration
//------------------------------------------------------------------------------
void cta::mediachanger::AcsProxyDummy::mountTapeReadWrite(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot) {
}
//------------------------------------------------------------------------------
// dismountTape
//------------------------------------------------------------------------------
void cta::mediachanger::AcsProxyDummy::dismountTape(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot) {
}
//------------------------------------------------------------------------------
// dismountTape
//------------------------------------------------------------------------------
void cta::mediachanger::AcsProxyDummy::forceDismountTape(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot) {
}
/*
* The CERN Tape Archive(CTA) project
* Copyright(C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "mediachanger/AcsProxy.hpp"
namespace cta {
namespace mediachanger {
/**
* Concrete class implementimg a dummy AcsProxy.
*/
class AcsProxyDummy: public AcsProxy {
public:
/**
* Request the CASTOR ACS daemon to mount the specified tape for read-only
* access into the tape drive in the specified library slot.
*
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
void mountTapeReadOnly(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot);
/**
* Request the CASTOR ACS daemon to mount the specifed tape for read/write
* access into the tape drive in the specified library slot.
*
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
void mountTapeReadWrite(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot);
/**
* Request the CASTOR ACS daemon to dismount the specifed tape from the tape
* drive in the specified library slot.
*
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
void dismountTape(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot);
/**
* Request the CASTOR ACS daemon to forcefully dismount the specifed tape
* from the tape drive in the specified library slot. Forcefully means
* rewinding and ejecting the tape if necessary.
*
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
void forceDismountTape(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot);
}; // class AcsProxyDummy
} // namespace mediachanger
} // namespace cta
......@@ -167,8 +167,7 @@ Frame createAcsForceDismountTapeFrame(const std::string &vid, const AcsLibrarySl
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
AcsProxyZmq::AcsProxyZmq(const unsigned short serverPort,
void *const zmqContext) throw():
AcsProxyZmq::AcsProxyZmq(void *const zmqContext, const unsigned short serverPort) throw():
m_serverPort(serverPort),
m_serverSocket(zmqContext, ZMQ_REQ) {
connectZmqSocketToLocalhost(m_serverSocket, serverPort);
......
......@@ -19,6 +19,7 @@
#pragma once
#include "mediachanger/AcsProxy.hpp"
#include "mediachanger/Constants.hpp"
#include "mediachanger/ZmqSocketMT.hpp"
#include <mutex>
......@@ -35,11 +36,11 @@ public:
/**
* Constructor.
*
* @param zmqContext The ZMQ context.
* @param serverPort The TCP/IP port on which the CASTOR ACS daemon is
* listening for ZMQ messages.
* @param zmqContext The ZMQ context.
*/
AcsProxyZmq(const unsigned short serverPort, void *const zmqContext) throw();
AcsProxyZmq(void *const zmqContext, const unsigned short serverPort = ACS_PORT) throw();
/**
* Request the CASTOR ACS daemon to mount the specified tape for read-only
......@@ -48,8 +49,7 @@ public:
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
void mountTapeReadOnly(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot);
void mountTapeReadOnly(const std::string &vid, const AcsLibrarySlot &librarySlot);
/**
* Request the CASTOR ACS daemon to mount the specifed tape for read/write
......@@ -58,8 +58,7 @@ public:
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
void mountTapeReadWrite(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot);
void mountTapeReadWrite(const std::string &vid, const AcsLibrarySlot &librarySlot);
/**
* Request the CASTOR ACS daemon to dismount the specifed tape from the tape
......@@ -68,8 +67,7 @@ public:
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
void dismountTape(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot);
void dismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot);
/**
* Request the CASTOR ACS daemon to forcefully dismount the specifed tape
......@@ -79,8 +77,7 @@ public:
* @param vid The volume identifier of the tape to be mounted.
* @param librarySlot The slot in the library that contains the tape drive.
*/
void forceDismountTape(const std::string &vid,
const cta::mediachanger::AcsLibrarySlot &librarySlot);
void forceDismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot);
private:
......
......@@ -25,7 +25,6 @@ PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles})
set (MEDIACHANGER_LIB_SRC_FILES
AcsLibrarySlot.cpp
AcsProxy.cpp
AcsProxyDummy.cpp
AcsProxyZmq.cpp
CmdLine.cpp
CmdLineTool.cpp
......@@ -41,7 +40,6 @@ set (MEDIACHANGER_LIB_SRC_FILES
MessageHeader.cpp
messages.cpp
MmcProxy.cpp
MmcProxyDummy.cpp
MmcProxyLog.cpp
MmcProxyNotSupported.cpp
${ProtoSources}
......@@ -49,12 +47,12 @@ set (MEDIACHANGER_LIB_SRC_FILES
RmcMarshal.hpp
RmcMountMsgBody.cpp
RmcProxy.cpp
RmcProxyDummy.cpp
RmcProxyTcpIp.cpp
RmcUnmountMsgBody.cpp
ScsiLibrarySlot.cpp
SmartZmqContext.cpp
TapeLibraryType.cpp
ZmqContextSingleton.cpp
ZmqMsg.cpp
ZmqSocket.cpp
ZmqSocketMT.cpp
......@@ -78,7 +76,6 @@ set (MEDIACHANGER_UNIT_TESTS_LIB_SRC_FILES
IoTest.cpp
LibrarySlotParserTest.cpp
ManualLibrarySlotTest.cpp
MediaChangerFacadeTest.cpp
MountCmdLine.cpp
MountCmdLineTest.cpp
ScsiLibrarySlotTest.cpp)
......
......@@ -98,10 +98,16 @@ const unsigned short ACS_PORT = 54521;
*/
const unsigned short RMC_PORT = 5014;
/**
* The network timeout of rmc communications should be several minutes due
* to the time it takes to mount and unmount tapes.
*/
const int RMC_NET_TIMEOUT = 600; // Timeout in seconds
/**
* The maximum number of attempts a retriable RMC request should be issued.
*/
const int RMC_MAXRQSTATTEMPTS = 10;
const int RMC_MAX_RQST_ATTEMPTS = 10;
/**
* The magic number to identify taped messages.
......
......@@ -133,6 +133,13 @@ bool cta::mediachanger::DismountCmdLine::getForce() const throw() {
return m_force;
}
//------------------------------------------------------------------------------
// getProgramName
//------------------------------------------------------------------------------
std::string cta::mediachanger::DismountCmdLine::getProgramName() {
return "cta-mediachanger-dismount";
}
//------------------------------------------------------------------------------
// processOption
//------------------------------------------------------------------------------
......@@ -166,10 +173,10 @@ void cta::mediachanger::DismountCmdLine::processOption(const int opt) {
// getUsage
//------------------------------------------------------------------------------
std::string cta::mediachanger::DismountCmdLine::getUsage() throw() {
return
return std::string() +
"Usage:\n"
"\n"
" cta-mediachanger-dismount [options] VID DRIVE_SLOT\n"
" " + getProgramName() + " [options] VID DRIVE_SLOT\n"
"\n"
"Where:\n"
"\n"
......
......@@ -109,6 +109,13 @@ public:
*/
bool getForce() const throw();
/**
* Return sthe program name.
*
* @return sthe program name.
*/
static std::string getProgramName();
private:
/**
......
......@@ -17,13 +17,10 @@
*/
#include "common/exception/Exception.hpp"
#include "common/log/StdoutLogger.hpp"
#include "common/utils/utils.hpp"
#include "mediachanger/AcsProxyZmq.hpp"
#include "mediachanger/DismountCmd.hpp"
#include "mediachanger/DismountCmdLine.hpp"
#include "mediachanger/RmcProxyTcpIp.hpp"
#include "mediachanger/MmcProxyNotSupported.hpp"
#include "mediachanger/SmartZmqContext.hpp"
#include <exception>
#include <google/protobuf/stubs/common.h>
......@@ -73,24 +70,8 @@ int main(const int argc, char *const *const argv) {
static int exceptionThrowingMain(const int argc, char *const *const argv) {
using namespace cta;
const int sizeOfIOThreadPoolForZMQ = 1;
mediachanger::SmartZmqContext
zmqContext(mediachanger::SmartZmqContext::instantiateZmqContext(sizeOfIOThreadPoolForZMQ));
mediachanger::AcsProxyZmq acs(mediachanger::ACS_PORT, zmqContext.get());
mediachanger::MmcProxyNotSupported mmc;
const unsigned short rmcPort = mediachanger::RMC_PORT;
const unsigned int rmcMaxRqstAttempts = mediachanger::RMC_MAXRQSTATTEMPTS;
// The network timeout of rmc communications should be several minutes due
// to the time it takes to mount and unmount tapes
const int rmcNetTimeout = 600; // Timeout in seconds
mediachanger::RmcProxyTcpIp rmc(rmcPort, rmcNetTimeout, rmcMaxRqstAttempts);
mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
log::StdoutLogger log(mediachanger::DismountCmdLine::getProgramName());
mediachanger::MediaChangerFacade mc(log);
mediachanger::DismountCmd cmd(std::cin, std::cout, std::cerr, mc);
......
......@@ -16,7 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mediachanger/AcsProxyZmq.hpp"
#include "mediachanger/Constants.hpp"
#include "mediachanger/MediaChangerFacade.hpp"
#include "mediachanger/MmcProxyLog.hpp"
#include "mediachanger/RmcProxyTcpIp.hpp"
#include "mediachanger/ZmqContextSingleton.hpp"
#include "common/exception/Exception.hpp"
namespace cta {
......@@ -25,46 +30,37 @@ namespace mediachanger {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
MediaChangerFacade::MediaChangerFacade(
AcsProxy &acs,
MmcProxy &mmc,
RmcProxy &rmc) throw():
m_acs(acs),
m_mmc(mmc),
m_rmc(rmc) {
}
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
MediaChangerFacade::MediaChangerFacade(
AcsProxy &acs,
RmcProxy &rmc) throw():
m_acs(acs),
m_mmc(m_mmcNotSupported),
m_rmc(rmc) {
MediaChangerFacade::MediaChangerFacade(log::Logger &log, void *const zmqContext) throw():
m_log(log),
m_zmqContext(zmqContext) {
}
//------------------------------------------------------------------------------
// mountTapeReadOnly
//------------------------------------------------------------------------------
void MediaChangerFacade::mountTapeReadOnly(
const std::string &vid, const LibrarySlot &slot) {
void MediaChangerFacade::mountTapeReadOnly(const std::string &vid, const LibrarySlot &slot) {
try {
const TapeLibraryType libraryType = slot.getLibraryType();
// Dispatch the appropriate helper method depending on library slot type
switch(libraryType) {
case TAPE_LIBRARY_TYPE_ACS:
return m_acs.mountTapeReadOnly(vid,
dynamic_cast<const AcsLibrarySlot&>(slot));
{
AcsProxyZmq acs(m_zmqContext);
return acs.mountTapeReadOnly(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_MANUAL:
return m_mmc.mountTapeReadOnly(vid,
dynamic_cast<const ManualLibrarySlot&>(slot));
{
MmcProxyLog mmc(m_log);
return mmc.mountTapeReadOnly(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_SCSI:
// SCSI media-changers to not support read-only mounts
return m_rmc.mountTapeReadWrite(vid,
dynamic_cast<const ScsiLibrarySlot&>(slot));
{
RmcProxyTcpIp rmc;
// SCSI media-changers to not support read-only mounts
return rmc.mountTapeReadWrite(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
}
default:
{
// Should never get here
......@@ -85,22 +81,27 @@ void MediaChangerFacade::mountTapeReadOnly(
//------------------------------------------------------------------------------
// mountTapeReadWrite
//------------------------------------------------------------------------------
void MediaChangerFacade::mountTapeReadWrite(
const std::string &vid, const LibrarySlot &slot) {
void MediaChangerFacade::mountTapeReadWrite(const std::string &vid, const LibrarySlot &slot) {
try {
const TapeLibraryType libraryType = slot.getLibraryType();
// Dispatch the appropriate helper method depending on library slot type
switch(libraryType) {
case TAPE_LIBRARY_TYPE_ACS:
return m_acs.mountTapeReadWrite(vid,
dynamic_cast<const AcsLibrarySlot&>(slot));
{
AcsProxyZmq acs(m_zmqContext);
return acs.mountTapeReadWrite(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_MANUAL:
return m_mmc.mountTapeReadWrite(vid,
dynamic_cast<const ManualLibrarySlot&>(slot));
{
MmcProxyLog mmc(m_log);
return mmc.mountTapeReadWrite(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_SCSI:
return m_rmc.mountTapeReadWrite(vid,
dynamic_cast<const ScsiLibrarySlot&>(slot));
{
RmcProxyTcpIp rmc;
return rmc.mountTapeReadWrite(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
}
default:
{
// Should never get here
......@@ -121,22 +122,27 @@ void MediaChangerFacade::mountTapeReadWrite(
//------------------------------------------------------------------------------
// dismountTape
//------------------------------------------------------------------------------
void MediaChangerFacade::dismountTape(
const std::string &vid, const LibrarySlot &slot) {
void MediaChangerFacade::dismountTape(const std::string &vid, const LibrarySlot &slot) {
try {
const TapeLibraryType libraryType = slot.getLibraryType();
// Dispatch the appropriate helper method depending on library slot type
switch(libraryType) {
case TAPE_LIBRARY_TYPE_ACS:
return m_acs.dismountTape(vid,
dynamic_cast<const AcsLibrarySlot&>(slot));
{
AcsProxyZmq acs(m_zmqContext);
return acs.dismountTape(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_MANUAL:
return m_mmc.dismountTape(vid,
dynamic_cast<const ManualLibrarySlot&>(slot));
{
MmcProxyLog mmc(m_log);
return mmc.dismountTape(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_SCSI:
return m_rmc.dismountTape(vid,
dynamic_cast<const ScsiLibrarySlot&>(slot));
{
RmcProxyTcpIp rmc;
return rmc.dismountTape(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
}
default:
{
// Should never get here
......@@ -157,22 +163,27 @@ void MediaChangerFacade::dismountTape(
//------------------------------------------------------------------------------
// forceDismountTape
//------------------------------------------------------------------------------
void MediaChangerFacade::forceDismountTape(
const std::string &vid, const LibrarySlot &slot) {
void MediaChangerFacade::forceDismountTape(const std::string &vid, const LibrarySlot &slot) {
try {
const TapeLibraryType libraryType = slot.getLibraryType();
// Dispatch the appropriate helper method depending on library slot type
switch(libraryType) {
case TAPE_LIBRARY_TYPE_ACS:
return m_acs.forceDismountTape(vid,
dynamic_cast<const AcsLibrarySlot&>(slot));
{
AcsProxyZmq acs(m_zmqContext);
return acs.forceDismountTape(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_MANUAL:
return m_mmc.forceDismountTape(vid,
dynamic_cast<const ManualLibrarySlot&>(slot));
{
MmcProxyLog mmc(m_log);
return mmc.forceDismountTape(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_SCSI:
return m_rmc.forceDismountTape(vid,
dynamic_cast<const ScsiLibrarySlot&>(slot));
{
RmcProxyTcpIp rmc;
return rmc.forceDismountTape(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
}
default:
{
// Should never get here
......
......@@ -18,23 +18,17 @@
#pragma once
#include "common/log/Logger.hpp"
#include "mediachanger/LibrarySlot.hpp"
#include "mediachanger/MmcProxy.hpp"
#include "mediachanger/MmcProxyNotSupported.hpp"
#include "mediachanger/RmcProxy.hpp"
#include "mediachanger/AcsProxy.hpp"
#include "mediachanger/ZmqContextSingleton.hpp"
#include <unistd.h>
#include <sys/types.h>
#include <string>
namespace cta {
namespace mediachanger {
/**
* Provides a facade to three communications proxies: acs, manual and rmc.
*
* This facade will forward requests to mount and dismount tapes to the
* appropriate communications proxy based on the type of library slot.
* A facade to multiple types of tape media changer.
*/
class MediaChangerFacade {
public:
......@@ -42,21 +36,12 @@ public:
/**
* Constructor.
*
* @param acs Proxy object representing the CASTOR ACS daemon.
* @param mmc Proxy object representing the manual media-changer.
* @param rmc Proxy object representing the rmcd daemon.
*/
MediaChangerFacade(AcsProxy &acs, MmcProxy &mmc, RmcProxy &rmc) throw();
/**
* Constructor.
*
* Use this constructor when manual media-changers are not to be supported.
*
* @param acs Proxy object representing the CASTOR ACS daemon.
* @param rmc Proxy object representing the rmcd daemon.
* @param log Object representing the API to the CTA logging system.
* @param zmqContext The ZMQ context. There is usually one ZMQ context within
* a program. Set this parameter in order for the MediaChangerFacade to share
* an already existing ZMQ context.
*/
MediaChangerFacade(AcsProxy &acs, RmcProxy &rmc) throw();
MediaChangerFacade(log::Logger &log, void *const zmqContext = ZmqContextSingleton::instance()) throw();
/**
* Requests the media changer to mount the specified tape for read-only
......@@ -104,25 +89,14 @@ public:
private:
/**