StringBuilder sb = new StringBuilder(); sb.append( "# Component '" ); sb.append( component.getName()); sb.append( "'" ); result.add( new BlockComment( file, sb.toString())); blockComponent.setName( component.getName()); result.add( blockComponent ); result.add( new BlockBlank( file, "\n" )); if( component.getExtendedComponent() != null ) { p = new BlockProperty( file, ParsingConstants.PROPERTY_GRAPH_EXTENDS, component.getExtendedComponent().getName()); blockComponent.getInnerBlocks().add( p ); if( ! Utils.isEmptyOrWhitespaces( component.getInstallerName())) { p = new BlockProperty( file, ParsingConstants.PROPERTY_COMPONENT_INSTALLER, component.getInstallerName()); blockComponent.getInnerBlocks().add( p ); String s = writeCollection( component.getFacets()); if( ! Utils.isEmptyOrWhitespaces( s )) { p = new BlockProperty( file, ParsingConstants.PROPERTY_COMPONENT_FACETS, s ); s = writeCollection( component.getChildren()); if( ! Utils.isEmptyOrWhitespaces( s )) { p = new BlockProperty( file, ParsingConstants.PROPERTY_GRAPH_CHILDREN, s );
@Test public void testFromGraphs_withExternal() throws Exception { Graphs graphs = new Graphs(); Component cA = new Component( "A" ).installerName( Constants.TARGET_INSTALLER ); graphs.getRootComponents().add( cA ); cA.addExportedVariable( new ExportedVariable( "A.port", "9000" )); cA.addExportedVariable( new ExportedVariable( "A.ip", null )); cA.addImportedVariable( new ImportedVariable( "B.port", false, true )); cA.addImportedVariable( new ImportedVariable( "B.ip", true, false )); Component cB = new Component( "B" ).installerName( Constants.TARGET_INSTALLER ); graphs.getRootComponents().add( cB ); cB.addExportedVariable( new ExportedVariable( "B.port", "9000" )); cB.addExportedVariable( new ExportedVariable( "B.ip", null )); compareGraphs( graphs, false ); }
ComponentData extendedComponentData = this.componentNameToComponentData.get( data.extendedComponentName ); if( extendedComponentData != null ) data.object.extendComponent( extendedComponentData.object ); else this.errors.addAll( data.error( ErrorCode.CO_INEXISTING_COMPONENT, component( data.extendedComponentName ))); FacetData facetData = this.facetNameToFacetData.get( s ); if( facetData != null ) data.object.associateFacet( facetData.object ); else this.errors.addAll( data.error( ErrorCode.CO_INEXISTING_FACET, facet( s ))); FacetData facetData = this.facetNameToFacetData.get( s ); if( componentData != null ) data.object.addChild( componentData.object ); else if( facetData != null ) data.object.addChild( facetData.object ); else this.errors.addAll( data.error( ErrorCode.CO_INEXISTING_CHILD, name( s )));
/** * Searches for a cycle in the facets inheritance. * @param component the component from which we introspect (not null) * @return null if no cycle was found, a string describing the cycle otherwise */ public static String searchForInheritanceCycle( Component component ) { String result = null; for( Component c = component.getExtendedComponent(); c != null && result == null; c = c.getExtendedComponent()) { if( c.equals( component )) result = component + " -> ... -> " + component; } return result; }
@Override public Component deserialize( JsonParser parser, DeserializationContext context ) throws IOException { ObjectCodec oc = parser.getCodec(); JsonNode node = oc.readTree( parser ); Component component = new Component(); JsonNode n; if(( n = node.get( NAME )) != null ) component.setName( n.textValue()); if(( n = node.get( COMP_INSTALLER )) != null ) component.setInstallerName( n.textValue()); return component; } }
/** * Finds the resource directory for an instance. * <p> * The resource directory may be the one of another component. * This is the case when a component extends another component. * </p> * <p> * An extending component can override the resource directory. * </p> * * @param applicationFilesDirectory the application's directory * @param component a component (may be null) * @return a non-null file (that may not exist) */ public static File findInstanceResourcesDirectory( File applicationFilesDirectory, Component component ) { File root = new File( applicationFilesDirectory, Constants.PROJECT_DIR_GRAPH ); File result = new File( "No recipe directory." ); Set<Component> alreadyChecked = new HashSet<> (); for( Component c = component; c != null; c = c.getExtendedComponent()) { // Prevent infinite loops for exotic cases if( alreadyChecked.contains( c )) break; alreadyChecked.add( c ); if(( result = new File( root, c.getName())).exists()) break; } return result; }
@Override public void serialize( Component component, JsonGenerator generator, SerializerProvider provider ) throws IOException { generator.writeStartObject(); if( component.getName() != null ) generator.writeStringField( NAME, component.getName()); String installerName = ComponentHelpers.findComponentInstaller( component ); if( installerName != null ) generator.writeStringField( COMP_INSTALLER, installerName ); generator.writeEndObject(); } }
@Test public void testChain() { Component c = new Component( "c" ); Component comp = new Component().name( "ins" ).installerName( "my-installer" ); comp.extendComponent( c ); Assert.assertEquals( "ins", comp.getName()); Assert.assertEquals( "my-installer", comp.getInstallerName()); Assert.assertEquals( c, comp.getExtendedComponent()); }
final String sectionName = DocConstants.SECTION_COMPONENTS + comp.getName(); StringBuilder section = startSection( sectionName ); section.append( renderTitle2( comp.getName())); section.append( renderTitle3( this.messages.get( "overview" ))); //$NON-NLS-1$ String customInfo = readCustomInformation( this.applicationDirectory, comp.getName(), DocConstants.COMP_SUMMARY ); if( Utils.isEmptyOrWhitespaces( customInfo )) customInfo = this.typeAnnotations.get( comp.getName()); AbstractRoboconfTransformer transformer = new InheritanceTransformer( comp, comp.getExtendedComponent(), extendingComponents, 4 ); saveImage( comp, DiagramType.INHERITANCE, transformer, section ); for( AbstractType type : comp.getAncestors()) { if( type instanceof Facet ) { ancestors.add( type ); for( AbstractType type : comp.getChildren()) { if( type instanceof Facet ) { children.add( type ); String s = readCustomInformation( this.applicationDirectory, comp.getName(), DocConstants.COMP_EXTRA ); if( ! Utils.isEmptyOrWhitespaces( s )) { section.append( renderTitle3( this.messages.get( "extra" ))); //$NON-NLS-1$
Component root = new Component( "root" ); Component serverWithApp = new Component( "server with app" ); Component serverWithAnotherApp = new Component( "server with another app" ); Component db = new Component( "database" ); root.addChild( db ); root.addChild( serverWithAnotherApp ); root.addChild( serverWithApp ); serverWithAnotherApp.extendComponent( serverWithApp ); serverWithApp.associateFacet( anotherServerFacet ); serverWithApp.addExportedVariable( new ExportedVariable( "ip", null )); serverWithApp.addExportedVariable( new ExportedVariable( serverWithApp.getName() + ".port", "8080" )); serverWithApp.addExportedVariable( new ExportedVariable( "env", "test" )); serverWithAnotherApp.addExportedVariable( new ExportedVariable( serverFacet.getName() + ".url-suffix", "another/path" )); serverWithAnotherApp.addExportedVariable( new ExportedVariable( "whatever", "something" )); serverWithAnotherApp.addExportedVariable( new ExportedVariable( "env", "prod" )); db.addExportedVariable( new ExportedVariable( "ip", null )); db.addExportedVariable( new ExportedVariable( "port", "3306" )); Assert.assertTrue( exports.containsKey( serverWithApp.getName() + ".ip" )); Assert.assertNull( exports.get( serverWithApp.getName() + ".ip" )); Assert.assertEquals( "8080", exports.get( serverWithApp.getName() + ".port" )); Assert.assertEquals( "test", exports.get( serverWithApp.getName() + ".env" )); Assert.assertEquals( "some/path", exports.get( serverWithApp.getName() + ".url-suffix" )); Assert.assertEquals( "some/path", exports.get( serverFacet.getName() + ".url-suffix" ));
Component comp = new Component(); Iterator<ModelError> iterator = RuntimeModelValidator.validate( comp ).iterator(); Assert.assertEquals( ErrorCode.RM_EMPTY_COMPONENT_NAME, iterator.next().getErrorCode()); comp.setName( "my # component" ); iterator = RuntimeModelValidator.validate( comp ).iterator(); Assert.assertEquals( ErrorCode.RM_INVALID_COMPONENT_NAME, iterator.next().getErrorCode()); comp.setName( "my.component" ); iterator = RuntimeModelValidator.validate( comp ).iterator(); Assert.assertEquals( ErrorCode.RM_DOT_IS_NOT_ALLOWED, iterator.next().getErrorCode()); comp.setName( "comp" ); iterator = RuntimeModelValidator.validate( comp ).iterator(); Assert.assertEquals( ErrorCode.RM_EMPTY_COMPONENT_INSTALLER, iterator.next().getErrorCode()); Assert.assertFalse( iterator.hasNext()); comp.setInstallerName( "my installer !!" ); iterator = RuntimeModelValidator.validate( comp ).iterator(); Assert.assertEquals( ErrorCode.RM_INVALID_COMPONENT_INSTALLER, iterator.next().getErrorCode()); Assert.assertFalse( iterator.hasNext()); comp.setInstallerName( "my installer" ); iterator = RuntimeModelValidator.validate( comp ).iterator(); Assert.assertEquals( ErrorCode.RM_ROOT_INSTALLER_MUST_BE_TARGET, iterator.next().getErrorCode()); Assert.assertFalse( iterator.hasNext()); comp.setInstallerName( Constants.TARGET_INSTALLER ); iterator = RuntimeModelValidator.validate( comp ).iterator();
Component cA = new Component( "A" ).installerName( Constants.TARGET_INSTALLER ); graphs.getRootComponents().add( cA ); cA.associateFacet( facet ); cA.addExportedVariable( new ExportedVariable( "A.port", "9000" )); cA.addExportedVariable( new ExportedVariable( "A.ip", null )); cA.addImportedVariable( new ImportedVariable( "B.ip", true, false )); cA.addImportedVariable( new ImportedVariable( "facetF.props", false, false )); Component cB = new Component( "B" ).installerName( "installer B" ); cB.addExportedVariable( new ExportedVariable( "B.port", "9000" )); cB.addExportedVariable( new ExportedVariable( "B.ip", null )); cB.associateFacet( facet ); cB.associateFacet( facet ); Component cC = new Component( "C" ).installerName( "installer C" ); for( Facet f : cB.getFacets()) cC.associateFacet( f ); cC.addExportedVariable( new ExportedVariable( "my-facet-2.woo", "woo" )); cC.addExportedVariable( new ExportedVariable( "C.port", "9000" )); cC.addExportedVariable( new ExportedVariable( "facetF.props", "something else" )); cA.addChild( cB ); cA.addChild( cC );
Component root1 = new Component( ROOT_1 ).installerName( Constants.TARGET_INSTALLER ); root1.associateFacet( facetVm ); graph.getRootComponents().add( root1 ); Component root2 = new Component( ROOT_2 ).installerName( Constants.TARGET_INSTALLER ); root2.associateFacet( facetVm ); graph.getRootComponents().add( root2 ); Component glassfish = new Component( GLASSFISH ).installerName( "puppet" ); glassfish.associateFacet( facetWeb ); glassfish.associateFacet( facetJee ); Component tomcat = new Component( TOMCAT ).installerName( "puppet" ); tomcat.associateFacet( facetWeb ); Component tomcat8 = new Component( TOMCAT_8 ); tomcat8.extendComponent( tomcat ); Component mySql = new Component( MYSQL ).installerName( "script" ); mySql.addExportedVariable( new ExportedVariable( "ip", null )); mySql.addExportedVariable( new ExportedVariable( "port", "3306" )); mySql.associateFacet( facetDb ); Component mongoWithoutFacet = new Component( MONGO_DB ).installerName( "Chef" ); mongoWithoutFacet.addExportedVariable( new ExportedVariable( "ip", null )); mongoWithoutFacet.addExportedVariable( new ExportedVariable( "port", "28017" )); root1.addChild( mongoWithoutFacet ); Component app1 = new Component( APP_1 ).installerName( "file" );
@Test public void testPuppetValidation_oneModuleButWildCardImports() throws Exception { File appDir = this.folder.newFolder(); Component comp = new Component( "toto" ).installerName( "puppet" ); comp.addImportedVariable( new ImportedVariable( "Other.*", true, false )); File directory = ResourceUtils.findInstanceResourcesDirectory( appDir, comp ); Assert.assertTrue( new File( directory, "roboconf_toto" ).mkdirs()); List<ModelError> errors = RecipesValidator.validateComponentRecipes( appDir, comp ); Assert.assertEquals( 1, errors.size()); Assert.assertEquals( ErrorCode.REC_PUPPET_DISLIKES_WILDCARD_IMPORTS, errors.get( 0 ).getErrorCode()); }
@Test public void testScriptValidation_noScriptAtAll() throws Exception { File appDir = this.folder.newFolder(); Component comp = new Component( "toto" ).installerName( "script" ); File directory = ResourceUtils.findInstanceResourcesDirectory( appDir, comp ); Assert.assertTrue( new File( directory, RecipesValidator.SCRIPTS_DIR_NAME ).mkdirs()); Assert.assertEquals( 0, RecipesValidator.validateComponentRecipes( appDir, comp ).size()); }
@Test public void testComponentResolutionWhenSurroundingSpaces() throws Exception { Component vmComponent = new Component( "VM" ).installerName( "target" ); Component aComponent = new Component( "A" ).installerName( "whatever" ); vmComponent.addChild( aComponent ); Graphs graphs = new Graphs(); graphs.getRootComponents().add( vmComponent ); File f = TestUtils.findTestFile( "/configurations/valid/instance-with-space-after.instances" ); FromInstanceDefinition fromDef = new FromInstanceDefinition( f.getParentFile()); Collection<Instance> rootInstances = fromDef.buildInstances( graphs, f ); Iterator<ParsingError> iterator = fromDef.getErrors().iterator(); Assert.assertFalse( iterator.hasNext()); Assert.assertEquals( 2, rootInstances.size()); for( Instance rootInstance : rootInstances ) { Assert.assertEquals( 1, rootInstance.getChildren().size()); Instance instance = rootInstance.getChildren().iterator().next(); Assert.assertEquals( "A", instance.getComponent().getName()); Assert.assertEquals( "A ", instance.getName()); } }
Component root1 = ComponentHelpers.findComponent( app.getGraphs(), ComplexApplicationFactory1.ROOT_1 ); Assert.assertNotNull( root1 ); Assert.assertEquals( 1, root1.getChildren().size()); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.GLASSFISH ))); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.TOMCAT ))); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.TOMCAT_8 ))); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.MYSQL ))); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.MONGO_DB ))); Assert.assertEquals( 0, root2.getChildren().size()); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.GLASSFISH ))); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.TOMCAT ))); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.TOMCAT_8 ))); Assert.assertTrue( children.contains( new Component( ComplexApplicationFactory1.MYSQL ))); Assert.assertEquals( 0, c.getChildren().size()); Assert.assertEquals( 0, ComponentHelpers.findAllChildren( c ).size()); Assert.assertEquals( 0, c.getChildren().size()); Assert.assertEquals( 0, ComponentHelpers.findAllChildren( c ).size()); Assert.assertEquals( 1, c.getChildren().size()); Assert.assertEquals( ComplexApplicationFactory1.APP_3, c.getChildren().iterator().next().getName()); Assert.assertEquals( ComplexApplicationFactory1.APP_1, lastChildren.get( 0 ).getName()); Assert.assertEquals( ComplexApplicationFactory1.APP_2, lastChildren.get( 1 ).getName()); Assert.assertEquals( ComplexApplicationFactory1.APP_3, lastChildren.get( 2 ).getName());
@Test public void testFindPrefixesForMandatoryImportedVariables() { Component component = new Component( "comp" ); component.addImportedVariable( new ImportedVariable( "comp.ip", false, false )); component.addImportedVariable( new ImportedVariable( "comp.split.property", false, false )); component.addImportedVariable( new ImportedVariable( "comp.port", false, false )); component.addImportedVariable( new ImportedVariable( "facet.desc", true, false )); component.addImportedVariable( new ImportedVariable( "facet-n.prop1", true, false )); component.addImportedVariable( new ImportedVariable( "facet-n.prop2", false, false )); Instance instance = new Instance( "inst" ).component( component ); Set<String> prefixes = VariableHelpers.findPrefixesForMandatoryImportedVariables( instance ); Assert.assertEquals( 2, prefixes.size()); Assert.assertTrue( prefixes.contains( "comp" )); Assert.assertTrue( prefixes.contains( "facet-n" )); component.importedVariables.clear(); prefixes = VariableHelpers.findPrefixesForMandatoryImportedVariables( instance ); Assert.assertEquals( 0, prefixes.size()); }
@Test public void testFindAllImportedVariables() { Component root = new Component( "root" ); Component serverWithApp = new Component( "server with app" ); Component serverWithAnotherApp = new Component( "server with another app" ); Component db = new Component( "database" ); root.addChild( db ); root.addChild( serverWithAnotherApp ); root.addChild( serverWithApp ); serverWithApp.addImportedVariable( new ImportedVariable( "database.ip", false, false )); serverWithApp.addImportedVariable( new ImportedVariable( "database.port", true, false )); serverWithApp.addExportedVariable( new ExportedVariable( "url", "something" )); serverWithAnotherApp.extendComponent( serverWithApp ); serverWithAnotherApp.addImportedVariable( new ImportedVariable( "database.port", false, false )); serverWithAnotherApp.addImportedVariable( new ImportedVariable( "whatever", false, false )); db.addExportedVariable( new ExportedVariable( "ip", null )); db.addExportedVariable( new ExportedVariable( "port", "3306" ));
@Test public void testFindInstanceResourcesDirectory_success() throws Exception { final File appDir = this.folder.newFolder(); final Component c1 = new Component( "c1" ); final Component c2 = new Component( "c2" ); final File expectedFile = new File( appDir, Constants.PROJECT_DIR_GRAPH + File.separator + c1.getName()); Assert.assertEquals( expectedFile, ResourceUtils.findInstanceResourcesDirectory( appDir, c1 )); Assert.assertNotSame( expectedFile, ResourceUtils.findInstanceResourcesDirectory( appDir, c2 )); c2.extendComponent( c1 ); Assert.assertEquals( expectedFile, ResourceUtils.findInstanceResourcesDirectory( appDir, c2 )); Instance instance = new Instance( "whatever" ).component( c2 ); Assert.assertEquals( expectedFile, ResourceUtils.findInstanceResourcesDirectory( appDir, instance )); }