/**
* Copyright 2014 Comcast Cable Communications Management, LLC
*
* This file is part of CATS.
*
* CATS 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.
*
* CATS 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 CATS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.comcast.cats;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.log4j.xml.DOMConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import com.comcast.cats.decorator.DecoratorFactory;
import com.comcast.cats.domain.SettopDesc;
import com.comcast.cats.domain.SettopGroup;
import com.comcast.cats.domain.exception.AllocationException;
import com.comcast.cats.domain.exception.ServiceInstantiationException;
import com.comcast.cats.domain.exception.SettopNotFoundException;
import com.comcast.cats.domain.service.SettopDomainService;
import com.comcast.cats.domain.util.AssertUtil;
import com.comcast.cats.domain.util.CommonUtil;
import com.comcast.cats.provider.SettopExclusiveAccessEnforcer;
/**
* Implementation of {@link SettopFactory}, which will use the domain API to
* create {@link SettopDesc}
*
* @author cfrede001,subinsugunan
* @since 2.0.0
*/
@Named
public class SettopFactoryImpl implements SettopFactory
{
private final Logger LOGGER = LoggerFactory.getLogger( getClass() );
private SettopDomainService settopDomainService;
private EnvironmentFactory environmentFactory;
private StringBuilder settopCreationErrorMessage = new StringBuilder( "" );
private SettopExclusiveAccessEnforcer settopExclusiveAccessEnforcer;
private DecoratorFactory decoratorFactory;
/**
* Constructor
* @param settopDomainService {@linkplain SettopDomainService}
* @param environmentFactory {@linkplain EnvironmentFactory}
* @param settopExclusiveAccessEnforcer {@linkplain SettopExclusiveAccessEnforcer}
* @param decoratorFactory {@linkplain DecoratorFactory}
*/
@Inject
public SettopFactoryImpl( SettopDomainService settopDomainService, EnvironmentFactory environmentFactory,
SettopExclusiveAccessEnforcer settopExclusiveAccessEnforcer,
DecoratorFactory decoratorFactory )
{
this.settopDomainService = settopDomainService;
this.environmentFactory = environmentFactory;
this.settopExclusiveAccessEnforcer = settopExclusiveAccessEnforcer;
this.decoratorFactory = decoratorFactory;
}
/**
* To find the settop with host mac id
* @param macId
* @return {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public Settop findSettopByHostMac( String macId ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmpty( macId, "Cannot search settops. macId cannot be null or empty" );
if ( !CommonUtil.isValidMacId( macId ) )
{
throw new SettopNotFoundException( "A proper macId is required for Settops creation." );
}
SettopDesc settopDesc = settopDomainService.findByMacId( macId );
SettopImpl settop = new SettopImpl();
settop.setSettopInfo( settopDesc );
try
{
environmentFactory.wireSettop( settop );
}
catch ( ServiceInstantiationException e )
{
throw new SettopNotFoundException( "Failed to create service interfaces for settop[" + macId + "], "
+ e.getMessage() );
}
settop.setLogger( getSettopLogger( settop.getLogDirectory() ) );
return decoratorFactory.decorate( settop );
}
/**
* To find the settop with host mac id
* @param macId
* @param isAllocationRequired
* @return {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public Settop findSettopByHostMac( String macId, boolean isAllocationRequired ) throws SettopNotFoundException,
AllocationException
{
Settop settop = findSettopByHostMac( macId );
if ( isAllocationRequired )
{
settopExclusiveAccessEnforcer.lock( settop );
}
return settop;
}
/**
* Convenience method to create a list of Settops from a list of SettopDesc
*
* @param settopDescList
* - List of descriptions to be used to create settops.
* @return - List of instantiated settop objects.
* @throws SettopNotFoundException
* - If SettopDesc list is empty or no settops were added.
*/
private List< Settop > createSettops( List< SettopDesc > settopDescList ) throws SettopNotFoundException
{
if ( null == settopDescList || settopDescList.isEmpty() )
{
throw new SettopNotFoundException( "Settop list is NULL or empty" );
}
List< Settop > settopList = new ArrayList< Settop >( settopDescList.size() );
SettopImpl settop = null;
for ( SettopDesc settopDesc : settopDescList )
{
if ( ( null != settopDesc ) && ( null != settopDesc.getEnvironmentId() ) )
{
LOGGER.info( "Creating Settop for" + settopDesc.toString() );
settop = new SettopImpl();
settop.setSettopInfo( settopDesc );
try
{
environmentFactory.wireSettop( settop );
settopList.add( settop );
settop.setLogger( getSettopLogger(settop.getLogDirectory()));
}
catch ( ServiceInstantiationException e )
{
throw new SettopNotFoundException( e );
}
}
else
{
LOGGER.error( "Settop creation failed for " + settopDesc
+ " Either SettopDesc was null or settopDesc.getEnvironmentId() was null" );
}
}
if ( settopList.size() <= 0 )
{
throw new SettopNotFoundException( "No Settops were able to be created" );
}
return settopList;
}
private Logger getSettopLogger( String logDirectory )
{
Map<String,String> mdcMap = new HashMap<String,String>();
mdcMap.put("SettopMac", logDirectory);
mdcMap.put("LogFileName", "RunTimeExecution.log");
MDC.setContextMap(mdcMap);
URL logFileUrl = getClass().getResource( "/settop-log4j.xml" );
// DOMConfigurator.configure( logFileUrl );
Logger settopLogger = LoggerFactory.getLogger("Settop");
return settopLogger;
}
/**
* To find the settop with unit address.
* @param unitAddress
* @return {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public Settop findSettopByUnitAddress( String unitAddress ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmpty( unitAddress, "Cannot search settops.UnitAddress cannot be null or empty" );
List< Settop > settops = findAllSettopByPropertyValues( SettopConstants.UNIT_ADDRESS_PROPERTY, new String[]
{ unitAddress } );
if ( settops.size() <= 0 )
{
throw new SettopNotFoundException( "No settop found with the given unitAddress = " + unitAddress );
}
return settops.get( 0 );
}
/**
* To find the settop with host ip address.
* @param ip
* @return {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public Settop findSettopByHostIpAddress( String ip ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmpty( ip, "Cannot search settops. Ip cannot be null or empty" );
if ( !CommonUtil.isValidIp( ip ) )
{
throw new SettopNotFoundException( "Cannot search settops. invalid IP format" );
}
List< Settop > settops = findAllSettopByPropertyValues( SettopConstants.HOST_IP_PROPERTY, new String[]
{ ip } );
if ( settops.size() <= 0 )
{
throw new SettopNotFoundException( "No settop found with the given host ip = " + ip );
}
return settops.get( 0 );
}
/**
* To find all settop by Remote Type.
* @param remoteType - String
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findAllSettopByRemoteType( String remoteType ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmpty( remoteType, "Cannot search settops. Remote type cannot be null or empty" );
List< Settop > settops = findAllSettopByPropertyValues( SettopConstants.REMOTE_TYPE_PROPERTY, new String[]
{ remoteType } );
if ( settops.size() <= 0 )
{
throw new SettopNotFoundException( "No settop found with the given remoteType = " + remoteType );
}
return settops;
}
/**
* To find all settop by model.
* @param model
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findAllSettopByModel( String model ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmpty( model, "Cannot search settops. Model cannot be null or empty" );
List< Settop > settops = findAllSettopByPropertyValues( SettopConstants.MODEL_PROPERTY, new String[]
{ model } );
if ( settops.size() <= 0 )
{
throw new SettopNotFoundException( "No settop found with the given model = " + model );
}
return settops;
}
/**
* To find all settop with property and values
* @param property
* @param value - String
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findAllSettopByPropertyValue( String property, String value ) throws SettopNotFoundException
{
return findAllSettopByPropertyValues( property, new String[]
{ value } );
}
/**
* To find all settop with property and values
* @param property
* @param values - String array
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findAllSettopByPropertyValues( String property, String[] values )
throws SettopNotFoundException
{
AssertUtil.isNullOrEmpty( property, "Cannot search settops. Property cannot be is null ot empty" );
AssertUtil.isNullOrEmpty( values, "Cannot search settops. Values cannot be is null ot empty" );
LOGGER.info( "Searching settops with property [" + property + "] " );
List< SettopDesc > settopDescList = settopDomainService.findAvailableByProperty( property, values );
return createSettops( settopDescList );
}
/**
* To find all the settop with criteria
* @param criteria
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findAllSettopByCriteria( Map< String, String > criteria ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmptyMap( criteria, "Cannot search settops. Criteria cannot be is null ot empty" );
LOGGER.info( "Searching settops with criteria [" + criteria + "]" );
List< SettopDesc > settopDescList = settopDomainService.findAvailableByCriteria( criteria );
return createSettops( settopDescList );
}
/**
* To find the settop with host mac id
* @param macIdList - List of String
* @param failOnCreateError
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findSettopByHostMac( List< String > macIdList, boolean failOnCreateError )
throws SettopNotFoundException
{
AssertUtil.isNullOrEmptyList( macIdList, "Cannot search settops. macIdList cannot be is null ot empty" );
List< Settop > settopList = new LinkedList< Settop >();
StringBuilder settopCreationErrorMessage = new StringBuilder( "" );
for ( String mac : macIdList )
{
try
{
settopList.add( findSettopByHostMac( mac ) );
}
catch ( SettopNotFoundException exception )
{
String error = "Unable to create settop for mac id " + mac + "-" + exception.getMessage() + "\n";
settopCreationErrorMessage.append( error );
if ( failOnCreateError )
{
throw new SettopNotFoundException( error );
}
}
}
// If no settops could be locked throw an exception.
if ( settopList.size() <= 0 )
{
throw new SettopNotFoundException( "Unable to create settops from the list" );
}
return settopList;
}
/**
* To find the settop by host mac id
* @param macIdList - List of String
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findSettopByHostMac( List< String > macIdList ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmptyList( macIdList, "Cannot search settops. macIdList cannot be is null ot empty" );
return findSettopByHostMac( macIdList, false );
}
/**
* To get settop creation error.
* @return String
*/
@Override
public String getSettopCreationError()
{
return settopCreationErrorMessage.toString();
}
/**
* To find all settop with group name.
* @param settopGroupName
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findAllSettopByGroupName( String settopGroupName ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmpty( settopGroupName, "settopGroupName cannot be null or empty" );
SettopGroup settopGroup = new SettopGroup();
settopGroup.setName( settopGroupName );
List< SettopDesc > settopDescList = settopDomainService.findAllBySettopGroup( settopGroup );
if ( ( null == settopDescList ) || ( settopDescList.isEmpty() ) )
{
throw new SettopNotFoundException( "No settop found for the given settop group : " + settopGroupName );
}
return createSettops( settopDescList );
}
/**
* To find available settop by group id.
* @param settopGroupName
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@Override
public List< Settop > findAvailableSettopByGroupName( String settopGroupName ) throws SettopNotFoundException
{
AssertUtil.isNullOrEmpty( settopGroupName, "settopGroupName cannot be null or empty" );
SettopGroup settopGroup = new SettopGroup();
settopGroup.setName( settopGroupName );
List< SettopDesc > settopDescList = settopDomainService.findAvailableBySettopGroup( settopGroup );
if ( ( null == settopDescList ) || ( settopDescList.isEmpty() ) )
{
throw new SettopNotFoundException( "No settop available in the given settop group : " + settopGroupName );
}
return createSettops( settopDescList );
}
/**
* To find all allocated settop.
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@SuppressWarnings( "unchecked" )
@Override
public List< Settop > findAllAllocatedSettop() throws SettopNotFoundException
{
@SuppressWarnings( "rawtypes" )
List settops = settopDomainService.findAllAllocated();
if ( ( null == settops ) || ( settops.isEmpty() ) )
{
throw new SettopNotFoundException( "No settop allocated for the current user" );
}
else
{
return createSettops( settops );
}
}
/**
* To find all available settop.
* @return List of {@linkplain Settop}
* @throws {@linkplain SettopNotFoundException}
*/
@SuppressWarnings( "unchecked" )
@Override
public List< Settop > findAllAvailableSettop() throws SettopNotFoundException
{
@SuppressWarnings( "rawtypes" )
List settops = settopDomainService.findAllAvailable();
if ( ( null == settops ) || ( settops.isEmpty() ) )
{
throw new SettopNotFoundException( "No settop available for the current user" );
}
else
{
return createSettops( settops );
}
}
}