Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright 2015-2016 Linagora, Université Joseph Fourier, Floralis
*
* The present code is developed in the scope of the joint LINAGORA -
* Université Joseph Fourier - Floralis research program and is designated
* as a "Result" pursuant to the terms and conditions of the LINAGORA
* - Université Joseph Fourier - Floralis research program. Each copyright
* holder of Results enumerated here above fully & independently holds complete
* ownership of the complete Intellectual Property rights applicable to the whole
* of said Results, and may freely exploit it in any manner which does not infringe
* the moral rights of the other copyright holders.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.roboconf.dm.internal.api.impl;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import net.roboconf.core.Constants;
import net.roboconf.core.model.beans.AbstractApplication;
import net.roboconf.core.model.beans.Application;
import net.roboconf.core.model.beans.ApplicationTemplate;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.model.helpers.InstanceHelpers;
import net.roboconf.core.model.runtime.TargetUsageItem;
import net.roboconf.core.model.runtime.TargetWrapperDescriptor;
import net.roboconf.core.utils.Utils;
import net.roboconf.dm.internal.api.impl.beans.InstanceContext;
import net.roboconf.dm.internal.utils.ConfigurationUtils;
import net.roboconf.dm.internal.utils.TargetHelpers;
import net.roboconf.dm.management.api.IConfigurationMngr;
import net.roboconf.dm.management.api.ITargetsMngr;
import net.roboconf.dm.management.exceptions.UnauthorizedActionException;
/**
* Here is the way this class stores information.
*
* Each target has an ID, which is an integer. And each target has its
* own directory, located under the DM's configuration directory.
*
*
* Each target may contain...
*
*
*
target.properties (mandatory)
*
{@value #TARGETS_ASSOC_FILE} (mapping between this target and application instances)
*
{@value #TARGETS_HINTS_FILE} (user preferences to show or hide targets for a given application)
*
{@value #TARGETS_USAGE_FILE} (mapping indicating which instances have deployed things with this target)
*
*
* @author Vincent Zurczak - Linagora
*/
public class TargetsMngrImpl implements ITargetsMngr {
private static final String TARGETS_ASSOC_FILE = "associations.properties";
private static final String TARGETS_HINTS_FILE = "hints.properties";
private static final String TARGETS_USAGE_FILE = "usage.properties";
private static final Object LOCK = new Object();
private final Logger logger = Logger.getLogger( getClass().getName());
private final AtomicInteger id = new AtomicInteger();
private final IConfigurationMngr configurationMngr;
private final Map instanceToCachedId;
/**
* Constructor.
* @param configurationMngr
*/
public TargetsMngrImpl( IConfigurationMngr configurationMngr ) {
this.configurationMngr = configurationMngr;
this.instanceToCachedId = new ConcurrentHashMap<> ();
// Restore the cache
restoreAssociationsCache();
}
// CRUD operations on targets
@Override
public String createTarget( String targetContent ) throws IOException {
File targetFile = new File( findTargetDirectory( null ), Constants.TARGET_PROPERTIES_FILE_NAME );
Utils.createDirectory( targetFile.getParentFile());
Utils.writeStringInto( targetContent, targetFile );
return targetFile.getParentFile().getName();
}
@Override
public String createTarget( File targetPropertiesFile ) throws IOException {
File targetFile = new File( findTargetDirectory( null ), Constants.TARGET_PROPERTIES_FILE_NAME );
Utils.createDirectory( targetFile.getParentFile());
Utils.copyStream( targetPropertiesFile, targetFile );
return targetFile.getParentFile().getName();
}
@Override
public void updateTarget( String targetId, String newTargetContent ) throws IOException, UnauthorizedActionException {
File targetFile = new File( findTargetDirectory( targetId ), Constants.TARGET_PROPERTIES_FILE_NAME );
if( ! targetFile.getParentFile().exists())
throw new UnauthorizedActionException( "Target " + targetId + " does not exist." );
Utils.writeStringInto( newTargetContent, targetFile );
}
@Override
public void deleteTarget( String targetId ) throws IOException, UnauthorizedActionException {
// No machine using this target can be running.
boolean used = false;
synchronized( LOCK ) {
used = isTargetUsed( targetId );
}
if( used )
throw new UnauthorizedActionException( "Deletion is not permitted." );
// Delete the files related to this target
File targetDirectory = findTargetDirectory( targetId );
Utils.deleteFilesRecursively( targetDirectory );
}
// Associating targets and application instances
@Override
public void associateTargetWithScopedInstance( String targetId, AbstractApplication app, String instancePath )
throws IOException, UnauthorizedActionException {
Instance instance = InstanceHelpers.findInstanceByPath( app, instancePath );
if( instance != null && instance.getStatus() != InstanceStatus.NOT_DEPLOYED )
throw new UnauthorizedActionException( "Operation not allowed: " + app + " :: " + instancePath + " should be not deployed." );
saveAssociation( app, targetId, instancePath, true );
}
@Override
public void dissociateTargetFromScopedInstance( AbstractApplication app, String instancePath )
throws IOException, UnauthorizedActionException {
Instance instance = InstanceHelpers.findInstanceByPath( app, instancePath );
if( instance != null && instance.getStatus() != InstanceStatus.NOT_DEPLOYED )
throw new UnauthorizedActionException( "Operation not allowed: " + app + " :: " + instancePath + " should be not deployed." );
saveAssociation( app, null, instancePath, false );
}
@Override
public void copyOriginalMapping( Application app ) throws IOException {
List keys = new ArrayList<> ();
// Null <=> The default for the application
keys.add( new InstanceContext( app.getTemplate(), (String) null ));
// We can search defaults only for the existing instances
for( Instance scopedInstance : InstanceHelpers.findAllScopedInstances( app ))
keys.add( new InstanceContext( app.getTemplate(), scopedInstance ));
// Copy the associations when they exist for the template
for( InstanceContext key : keys ) {
String targetId = this.instanceToCachedId.get( key );
try {
if( targetId != null )
associateTargetWithScopedInstance( targetId, app, key.getInstancePath());
} catch( UnauthorizedActionException e ) {
// This method could be used to reset the mappings / associations.
// However, this is not possible if the current instance is already deployed.
// So, we just skip it.
this.logger.severe( e.getMessage());
Utils.logException( this.logger, e );
}
}
}
@Override
public void applicationWasDeleted( AbstractApplication app ) throws IOException {
String name = app.getName();
String qualifier = app instanceof ApplicationTemplate ? ((ApplicationTemplate) app).getQualifier() : null;
List toClean = new ArrayList<> ();
Set targetIds = new HashSet<> ();
// Find the mapping keys and the targets to update
for( Map.Entry entry : this.instanceToCachedId.entrySet()) {
if( Objects.equals( name, entry.getKey().getName())
&& Objects.equals( qualifier, entry.getKey().getQualifier())) {
targetIds.add( entry.getValue());
toClean.add( entry.getKey());
}
}
// Update the target files
for( String targetId : targetIds ) {
File targetDirectory = findTargetDirectory( targetId );
// Update the association file
File[] files = new File[] {
new File( targetDirectory, TARGETS_ASSOC_FILE ),
new File( targetDirectory, TARGETS_HINTS_FILE )
};
for( File f : files ) {
for( InstanceContext key : toClean ) {
Properties props = Utils.readPropertiesFileQuietly( f, this.logger );
props.remove( key.toString());
writeProperties( props, f );
}
}
}
// Update the cache
for( InstanceContext key : toClean )
this.instanceToCachedId.remove( key );
}
// Finding targets
@Override
public Map findRawTargetProperties( AbstractApplication app, String instancePath ) {
Map result = new HashMap<> ();
String targetId = findTargetId( app, instancePath );
if( targetId != null ) {
File f = new File( findTargetDirectory( targetId ), Constants.TARGET_PROPERTIES_FILE_NAME );
for( Map.Entry