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

Simplified implementation of MediaChangerFacade

parent 52256599
......@@ -18,6 +18,7 @@
#include "mediachanger/AcsDismountTape.pb.h"
#include "mediachanger/AcsForceDismountTape.pb.h"
#include "mediachanger/AcsLibrarySlot.hpp"
#include "mediachanger/AcsMountTapeReadOnly.pb.h"
#include "mediachanger/AcsMountTapeReadWrite.pb.h"
#include "mediachanger/AcsProxyZmq.hpp"
......@@ -176,12 +177,11 @@ AcsProxyZmq::AcsProxyZmq(void *const zmqContext, const unsigned short serverPort
//------------------------------------------------------------------------------
// mountTapeReadOnly
//------------------------------------------------------------------------------
void AcsProxyZmq::mountTapeReadOnly(const std::string &vid,
const AcsLibrarySlot &librarySlot) {
void AcsProxyZmq::mountTapeReadOnly(const std::string &vid, const LibrarySlot &librarySlot) {
std::lock_guard<std::mutex> lock(m_mutex);
try {
const Frame rqst = createAcsMountTapeReadOnlyFrame(vid, librarySlot);
const Frame rqst = createAcsMountTapeReadOnlyFrame(vid, dynamic_cast<const AcsLibrarySlot&>(librarySlot));
sendFrame(m_serverSocket, rqst);
MediaChangerReturnValue reply;
......@@ -205,12 +205,11 @@ void AcsProxyZmq::mountTapeReadOnly(const std::string &vid,
//------------------------------------------------------------------------------
// mountTapeReadWrite
//------------------------------------------------------------------------------
void AcsProxyZmq::mountTapeReadWrite(const std::string &vid,
const AcsLibrarySlot &librarySlot) {
void AcsProxyZmq::mountTapeReadWrite(const std::string &vid, const LibrarySlot &librarySlot) {
std::lock_guard<std::mutex> lock(m_mutex);
try {
const Frame rqst = createAcsMountTapeReadWriteFrame(vid, librarySlot);
const Frame rqst = createAcsMountTapeReadWriteFrame(vid, dynamic_cast<const AcsLibrarySlot&>(librarySlot));
sendFrame(m_serverSocket, rqst);
MediaChangerReturnValue reply;
......@@ -234,12 +233,11 @@ void AcsProxyZmq::mountTapeReadWrite(const std::string &vid,
//------------------------------------------------------------------------------
// dismountTape
//------------------------------------------------------------------------------
void AcsProxyZmq::dismountTape(const std::string &vid,
const AcsLibrarySlot &librarySlot) {
void AcsProxyZmq::dismountTape(const std::string &vid, const LibrarySlot &librarySlot) {
std::lock_guard<std::mutex> lock(m_mutex);
try {
const Frame rqst = createAcsDismountTapeFrame(vid, librarySlot);
const Frame rqst = createAcsDismountTapeFrame(vid, dynamic_cast<const AcsLibrarySlot&>(librarySlot));
sendFrame(m_serverSocket, rqst);
MediaChangerReturnValue reply;
......@@ -263,12 +261,11 @@ void AcsProxyZmq::dismountTape(const std::string &vid,
//------------------------------------------------------------------------------
// forceDismountTape
//------------------------------------------------------------------------------
void AcsProxyZmq::forceDismountTape(const std::string &vid,
const AcsLibrarySlot &librarySlot) {
void AcsProxyZmq::forceDismountTape(const std::string &vid, const LibrarySlot &librarySlot) {
std::lock_guard<std::mutex> lock(m_mutex);
try {
const Frame rqst = createAcsForceDismountTapeFrame(vid, librarySlot);
const Frame rqst = createAcsForceDismountTapeFrame(vid, dynamic_cast<const AcsLibrarySlot&>(librarySlot));
sendFrame(m_serverSocket, rqst);
MediaChangerReturnValue reply;
......
......@@ -18,8 +18,8 @@
#pragma once
#include "mediachanger/AcsProxy.hpp"
#include "mediachanger/Constants.hpp"
#include "mediachanger/MediaChangerProxy.hpp"
#include "mediachanger/ZmqSocketMT.hpp"
#include <mutex>
......@@ -30,7 +30,7 @@ namespace mediachanger {
/**
* Concrete class providing a ZMQ implementation of an AcsProxy.
*/
class AcsProxyZmq: public AcsProxy {
class AcsProxyZmq: public MediaChangerProxy {
public:
/**
......@@ -49,7 +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 AcsLibrarySlot &librarySlot);
void mountTapeReadOnly(const std::string &vid, const LibrarySlot &librarySlot) override;
/**
* Request the CASTOR ACS daemon to mount the specifed tape for read/write
......@@ -58,7 +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 AcsLibrarySlot &librarySlot);
void mountTapeReadWrite(const std::string &vid, const LibrarySlot &librarySlot) override;
/**
* Request the CASTOR ACS daemon to dismount the specifed tape from the tape
......@@ -67,7 +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 AcsLibrarySlot &librarySlot);
void dismountTape(const std::string &vid, const LibrarySlot &librarySlot) override;
/**
* Request the CASTOR ACS daemon to forcefully dismount the specifed tape
......@@ -77,7 +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 AcsLibrarySlot &librarySlot);
void forceDismountTape(const std::string &vid, const LibrarySlot &librarySlot) override;
private:
......
......@@ -24,7 +24,6 @@ PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles})
set (MEDIACHANGER_LIB_SRC_FILES
AcsLibrarySlot.cpp
AcsProxy.cpp
AcsProxyZmq.cpp
CmdLine.cpp
CmdLineTool.cpp
......@@ -37,16 +36,15 @@ set (MEDIACHANGER_LIB_SRC_FILES
LibrarySlotParser.cpp
ManualLibrarySlot.cpp
MediaChangerFacade.cpp
MediaChangerProxy.cpp
MessageHeader.cpp
messages.cpp
MmcProxy.cpp
MmcProxyLog.cpp
MmcProxyNotSupported.cpp
${ProtoSources}
RmcMarshal.cpp
RmcMarshal.hpp
RmcMountMsgBody.cpp
RmcProxy.cpp
RmcProxyTcpIp.cpp
RmcUnmountMsgBody.cpp
ScsiLibrarySlot.cpp
......
......@@ -16,13 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common/exception/Exception.hpp"
#include "common/make_unique.hpp"
#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 {
namespace mediachanger {
......@@ -40,39 +41,10 @@ MediaChangerFacade::MediaChangerFacade(log::Logger &log, void *const zmqContext)
//------------------------------------------------------------------------------
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:
{
AcsProxyZmq acs(m_zmqContext);
return acs.mountTapeReadOnly(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_MANUAL:
{
MmcProxyLog mmc(m_log);
return mmc.mountTapeReadOnly(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_SCSI:
{
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
cta::exception::Exception ex;
ex.getMessage() << "Library slot has an unexpected library type";
throw ex;
}
}
return createMediaChangerProxy(slot.getLibraryType())->mountTapeReadOnly(vid, slot);
} catch(cta::exception::Exception &ne) {
cta::exception::Exception ex;
ex.getMessage() << "Failed to mount tape for read-only access"
": vid=" << vid << " slot=" << slot.str() << ": " <<
ex.getMessage() << "Failed to mount tape for read-only access: vid=" << vid << " slot=" << slot.str() << ": " <<
ne.getMessage().str();
throw ex;
}
......@@ -83,37 +55,10 @@ void MediaChangerFacade::mountTapeReadOnly(const std::string &vid, const Library
//------------------------------------------------------------------------------
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:
{
AcsProxyZmq acs(m_zmqContext);
return acs.mountTapeReadWrite(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_MANUAL:
{
MmcProxyLog mmc(m_log);
return mmc.mountTapeReadWrite(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_SCSI:
{
RmcProxyTcpIp rmc;
return rmc.mountTapeReadWrite(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
}
default:
{
// Should never get here
cta::exception::Exception ex;
ex.getMessage() << "Library slot has an unexpected library type";
throw ex;
}
}
return createMediaChangerProxy(slot.getLibraryType())->mountTapeReadWrite(vid, slot);
} catch(cta::exception::Exception &ne) {
cta::exception::Exception ex;
ex.getMessage() << "Failed to mount tape for read/write access"
": vid=" << vid << " slot=" << slot.str() << ": " <<
ex.getMessage() << "Failed to mount tape for read/write access: vid=" << vid << " slot=" << slot.str() << ": " <<
ne.getMessage().str();
throw ex;
}
......@@ -124,37 +69,10 @@ void MediaChangerFacade::mountTapeReadWrite(const std::string &vid, const Librar
//------------------------------------------------------------------------------
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:
{
AcsProxyZmq acs(m_zmqContext);
return acs.dismountTape(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_MANUAL:
{
MmcProxyLog mmc(m_log);
return mmc.dismountTape(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
}
case TAPE_LIBRARY_TYPE_SCSI:
{
RmcProxyTcpIp rmc;
return rmc.dismountTape(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
}
default:
{
// Should never get here
cta::exception::Exception ex;
ex.getMessage() << "Library slot has an unexpected library type";
throw ex;
}
}
return createMediaChangerProxy(slot.getLibraryType())->dismountTape(vid, slot);
} catch(cta::exception::Exception &ne) {
cta::exception::Exception ex;
ex.getMessage() << "Failed to dismount tape"
": vid=" << vid << " slot=" << slot.str() << ": " <<
ex.getMessage() << "Failed to dismount tape: vid=" << vid << " slot=" << slot.str() << ": " <<
ne.getMessage().str();
throw ex;
}
......@@ -165,39 +83,33 @@ void MediaChangerFacade::dismountTape(const std::string &vid, const LibrarySlot
//------------------------------------------------------------------------------
void MediaChangerFacade::forceDismountTape(const std::string &vid, const LibrarySlot &slot) {
try {
const TapeLibraryType libraryType = slot.getLibraryType();
return createMediaChangerProxy(slot.getLibraryType())->forceDismountTape(vid, slot);
} catch(cta::exception::Exception &ne) {
cta::exception::Exception ex;
ex.getMessage() << "Failed to force dismount tape: vid=" << vid << " slot=" << slot.str() << ": " <<
ne.getMessage().str();
throw ex;
}
}
// Dispatch the appropriate helper method depending on library slot type
//------------------------------------------------------------------------------
// createMediaChangerProxy
//------------------------------------------------------------------------------
std::unique_ptr<MediaChangerProxy> MediaChangerFacade::createMediaChangerProxy(const TapeLibraryType libraryType) {
try {
switch(libraryType) {
case TAPE_LIBRARY_TYPE_ACS:
{
AcsProxyZmq acs(m_zmqContext);
return acs.forceDismountTape(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
}
return make_unique<AcsProxyZmq>(m_zmqContext);
case TAPE_LIBRARY_TYPE_MANUAL:
{
MmcProxyLog mmc(m_log);
return mmc.forceDismountTape(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
}
return make_unique<MmcProxyLog>(m_log);
case TAPE_LIBRARY_TYPE_SCSI:
{
RmcProxyTcpIp rmc;
return rmc.forceDismountTape(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
}
return make_unique<RmcProxyTcpIp>();
default:
{
// Should never get here
cta::exception::Exception ex;
ex.getMessage() << "Library slot has an unexpected library type";
throw ex;
}
// Should never get here
throw exception::Exception("Library slot has an unexpected library type");
}
} catch(cta::exception::Exception &ne) {
cta::exception::Exception ex;
ex.getMessage() << "Failed to force dismount tape"
": vid=" << vid << " slot=" << slot.str() << ": " <<
ne.getMessage().str();
throw ex;
} catch(cta::exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
......
......@@ -20,8 +20,10 @@
#include "common/log/Logger.hpp"
#include "mediachanger/LibrarySlot.hpp"
#include "mediachanger/MediaChangerProxy.hpp"
#include "mediachanger/ZmqContextSingleton.hpp"
#include <memory>
#include <string>
namespace cta {
......@@ -98,6 +100,14 @@ private:
*/
void *m_zmqContext;
/**
* Factory method that creates a media changer proxy object based on the
* specified tape library type.
*
* @param libraryType The type of tape library.
*/
std::unique_ptr<MediaChangerProxy> createMediaChangerProxy(const TapeLibraryType libraryType);
}; // class MediaChangerFacade
} // namespace mediachanger
......
......@@ -16,10 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mediachanger/AcsProxy.hpp"
#include "mediachanger/MediaChangerProxy.hpp"
//-----------------------------------------------------------------------------
// destructor
//-----------------------------------------------------------------------------
cta::mediachanger::AcsProxy::~AcsProxy() {
cta::mediachanger::MediaChangerProxy::~MediaChangerProxy() {
}
......@@ -18,7 +18,7 @@
#pragma once
#include "mediachanger/AcsLibrarySlot.hpp"
#include "mediachanger/LibrarySlot.hpp"
#include <stdint.h>
#include <string>
......@@ -27,19 +27,19 @@ namespace cta {
namespace mediachanger {
/**
* Abstract class defining the interface to a proxy object representing the
* CASTOR ACS daemon.
* Abstract class defining the interface to a proxy object representing a
* media changer daemon.
*/
class AcsProxy {
class MediaChangerProxy {
public:
/**
* Destructor.
*/
virtual ~AcsProxy() = 0;
virtual ~MediaChangerProxy() = 0;
/**
* Request the CASTOR ACS daemon to mount the specified tape for read-only
* Request the media changer daemon to mount the specified tape for read-only
* access into the tape drive in the specified library slot.
*
* Please note that this method provides a best-effort service because not all
......@@ -48,28 +48,28 @@ 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 AcsLibrarySlot &librarySlot) = 0;
virtual void mountTapeReadOnly(const std::string &vid, const LibrarySlot &librarySlot) = 0;
/**
* Request the CASTOR ACS daemon to mount the specifed tape for read/write
* Request the media changer 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.
*/
virtual void mountTapeReadWrite(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
virtual void mountTapeReadWrite(const std::string &vid, const LibrarySlot &librarySlot) = 0;
/**
* Request the CASTOR ACS daemon to dismount the specifed tape from the tape
* drive in the specified library slot.
* Request the media changer 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.
*/
virtual void dismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
virtual void dismountTape(const std::string &vid, const LibrarySlot &librarySlot) = 0;
/**
* Request the CASTOR ACS daemon to forcefully dismount the specifed tape
* Request the media changer 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.
*
......@@ -79,9 +79,9 @@ 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 AcsLibrarySlot &librarySlot) = 0;
virtual void forceDismountTape(const std::string &vid, const LibrarySlot &librarySlot) = 0;
}; // class AcsProxy
}; // class MediaChangerProxy
} // namespace mediachanger
} // namespace cta
......
/*
* 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/MmcProxy.hpp"
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
cta::mediachanger::MmcProxy::~MmcProxy() throw() {
}
/*
* 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/ManualLibrarySlot.hpp"
#include <string>
namespace cta {
namespace mediachanger {
/**
* Asbtract class defining the interface to manually operated media-changer.
*/
class MmcProxy {
public:
/**
* Destructor.
*/
virtual ~MmcProxy() throw() = 0;
/**
* Requests the media changer to mount of the specified tape for read-only
* access into the drive in the specified library slot.
*
* Please note that this method provides a best-effort service because not all
* media changers support read-only mounts.
*
* @param vid The volume identifier of the tape.
* @param librarySlot The library slot containing the tape drive.
*/
virtual void mountTapeReadOnly(const std::string &vid,
const cta::mediachanger::ManualLibrarySlot &librarySlot) = 0;
/**
* Requests the media changer to mount of the specified tape for read/write
* access into the drive in the specified library slot.
*
* @param vid The volume identifier of the tape.
* @param librarySlot The library slot containing the tape drive.
*/
virtual void mountTapeReadWrite(const std::string &vid,
const cta::mediachanger::ManualLibrarySlot &librarySlot) = 0;
/**
* Requests the media changer to dismount of the specified tape from the
* drive in the specifed library slot.
*
* @param vid The volume identifier of the tape.
* @param librarySlot The library slot containing the tape drive.
*/
virtual void dismountTape(const std::string &vid,
const cta::mediachanger::ManualLibrarySlot &librarySlot) = 0;
/**
* Requests the media changer to forcefully dismount the specified tape from
* the drive in the specifed library slot. Forcefully means rewinding and
* ejecting the tape where necessary.
*
* Please note that this method provides a best-effort service because not all
* media changers support forceful dismounts.
*
* @param vid The volume identifier of the tape.
* @param librarySlot The library slot containing the tape drive.
*/
virtual void forceDismountTape(const std::string &vid,
const cta::mediachanger::ManualLibrarySlot &librarySlot) = 0;
}; // class MmcProxy
} // namespace mediachanger
} // namespace cta
......@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mediachanger/ManualLibrarySlot.hpp"
#include "mediachanger/MmcProxyLog.hpp"
//------------------------------------------------------------------------------
......@@ -28,8 +29,7 @@ cta::mediachanger::MmcProxyLog::MmcProxyLog(log::Logger &log) throw():
//------------------------------------------------------------------------------
// mountTapeReadOnly
//------------------------------------------------------------------------------
void cta::mediachanger::MmcProxyLog::mountTapeReadOnly(
const std::string &vid, const ManualLibrarySlot &librarySlot) {
void cta::mediachanger::MmcProxyLog::mountTapeReadOnly( const std::string &vid, const LibrarySlot &librarySlot) {
std::list<log::Param> params = {
log::Param("TPVID", vid),
log::Param("librarySlot", librarySlot.str())};
......@@ -40,8 +40,7 @@ void cta::mediachanger::MmcProxyLog::mountTapeReadOnly(
//------------------------------------------------------------------------------
// mountTapeReadWrite
//------------------------------------------------------------------------------
void cta::mediachanger::MmcProxyLog::mountTapeReadWrite(
const std::string &vid, const ManualLibrarySlot &librarySlot) {
void cta::mediachanger::MmcProxyLog::mountTapeReadWrite(const std::string &vid, const LibrarySlot &librarySlot) {
std::list<log::Param> params = {
log::Param("TPVID", vid),
log::Param("librarySlot", librarySlot.str())};
......@@ -52,8 +51,7 @@ void cta::mediachanger::MmcProxyLog::mountTapeReadWrite(
//------------------------------------------------------------------------------
// dismountTape
//------------------------------------------------------------------------------
void cta::mediachanger::MmcProxyLog::dismountTape(
const std::string &vid, const ManualLibrarySlot &librarySlot) {
void cta::mediachanger::MmcProxyLog::dismountTape( const std::string &vid, const LibrarySlot &librarySlot) {
std::list<log::Param> params = {
log::Param("TPVID", vid),
log::<