Input: The then () method accepts a { [CODESPLIT] @ Override public Decision < T , U > then ( BiConsumer < FactMap < T > , Result < U > > action ) { _rule . getThen ( ) . add ( action ) ; return this ; }


Input: The then () method accepts a { [CODESPLIT] @ Override public Decision < T , U > then ( Consumer < FactMap < T > > action ) { _rule . then ( action ) ; return this ; }


Input: The using () method reduces the facts to those specifically named here . The using () method only applies to the then () method immediately following it . [CODESPLIT] @ Override @ SuppressWarnings ( "unchecked" ) public Decision < T , U > using ( String ... factNames ) { _rule . using ( factNames ) ; return this ; }


Input: Registers a rule to be audited . [CODESPLIT] public void registerRule ( Auditable rule ) { _lock . writeLock ( ) . lock ( ) ; try { _auditMap . put ( rule . getName ( ) , new HashMap <> ( ) ) ; } finally { _lock . writeLock ( ) . unlock ( ) ; } }


Input: Updates the status of the rule & stores the status with the Auditor . [CODESPLIT] public void updateRuleStatus ( Auditable rule , RuleStatus status ) { _lock . readLock ( ) . lock ( ) ; try { if ( _auditMap . containsKey ( rule . getName ( ) ) ) { _lock . readLock ( ) . unlock ( ) ; _lock . writeLock ( ) . lock ( ) ; try { _auditMap . get ( rule . getName ( ) ) . put ( Thread . currentThread ( ) . getId ( ) , status ) ; _lock . readLock ( ) . lock ( ) ; } finally { _lock . writeLock ( ) . unlock ( ) ; } } } finally { _lock . readLock ( ) . unlock ( ) ; } }


Input: Gets a map of each rule name with its associated status . [CODESPLIT] public Map < String , RuleStatus > getRuleStatusMap ( ) { _lock . readLock ( ) . lock ( ) ; try { return _auditMap . keySet ( ) . stream ( ) . collect ( Collectors . toMap ( key -> key , key -> _auditMap . get ( key ) . getOrDefault ( Thread . currentThread ( ) . getId ( ) , RuleStatus . PENDING ) ) ) ; } finally { _lock . readLock ( ) . unlock ( ) ; } }


Input: Specifies the Result type for the RuleBook . [CODESPLIT] public < U > RuleBookWithResultTypeBuilder < U > withResultType ( Class < U > resultType ) { _resultType = resultType ; return new RuleBookWithResultTypeBuilder < U > ( ( new RuleBookBuilder < U > ( this ) ) . newRuleBook ( ) ) ; }


Input: Adds a rule to the RuleBook . [CODESPLIT] public RuleBookAddRuleBuilder < T > addRule ( Consumer < RuleBookRuleBuilder < T > > consumer ) { return new RuleBookAddRuleBuilder <> ( newRuleBook ( ) , consumer ) ; }


Input: Adds a rule to the RuleBook . [CODESPLIT] public < U > RuleBookAddRuleBuilder < T > addRule ( Rule < U , T > rule ) { return new RuleBookAddRuleBuilder <> ( newRuleBook ( ) , rule ) ; }


Input: The run ( Object [] ) method runs the { [CODESPLIT] @ Override @ SuppressWarnings ( "unchecked" ) public void run ( Object ... otherArgs ) { try { //only use facts of the specified type FactMap < T > typeFilteredFacts = new FactMap < T > ( ( Map < String , NameValueReferable < T > > ) _facts . values ( ) . stream ( ) . filter ( ( Object fact ) -> _factType . isAssignableFrom ( ( ( Fact ) fact ) . getValue ( ) . getClass ( ) ) ) . collect ( Collectors . toMap ( fact -> ( ( Fact ) fact ) . getName ( ) , fact -> ( Fact < T > ) fact ) ) ) ; //invoke then() action(s) if when() is true or if when() was never specified if ( getWhen ( ) == null || getWhen ( ) . test ( typeFilteredFacts ) ) { //iterate through the then() actions specified List < Object > actionList = getThen ( ) ; for ( int i = 0 ; i < ( getThen ( ) ) . size ( ) ; i ++ ) { Object action = actionList . get ( i ) ; List < String > factNames = _factNameMap . get ( i ) ; //if using() fact names were specified for the specific then(), use only those facts specified FactMap < T > usingFacts ; if ( factNames != null ) { usingFacts = new FactMap < T > ( factNames . stream ( ) . filter ( typeFilteredFacts :: containsKey ) . collect ( Collectors . toMap ( name -> name , name -> _facts . get ( name ) ) ) ) ; } else { usingFacts = typeFilteredFacts ; } //invoke the action Stream . of ( action . getClass ( ) . getMethods ( ) ) . filter ( method -> method . getName ( ) . equals ( "accept" ) ) . findFirst ( ) . ifPresent ( method -> { try { method . setAccessible ( true ) ; method . invoke ( action , ArrayUtils . combine ( new Object [ ] { usingFacts } , otherArgs , method . getParameterCount ( ) ) ) ; } catch ( IllegalAccessException | InvocationTargetException err ) { LOGGER . error ( "Error invoking action on " + action . getClass ( ) , err ) ; } } ) ; } //if stop() was invoked, stop the rule chain after then is finished executing if ( _ruleState == BREAK ) { return ; } } } catch ( Exception ex ) { //catch errors in case something like one rule was chained expecting a Fact that doesn't exist //eventually, we'll have to resolve that kind of issue ahead of time LOGGER . error ( "Error occurred when trying to evaluate rule!" , ex ) ; } //continue down the rule chain _nextRule . ifPresent ( rule -> rule . given ( _facts ) ) ; _nextRule . ifPresent ( Rule :: run ) ; }


Input: The given () method accepts a name / value pair to be used as a Fact . [CODESPLIT] @ Override @ SuppressWarnings ( "unchecked" ) public Rule < T > given ( String name , T value ) { _facts . put ( name , new Fact < T > ( name , value ) ) ; return this ; }


Input: The given () method accepts Facts to be evaluated in the Rule . [CODESPLIT] @ Override @ SuppressWarnings ( "unchecked" ) public Rule < T > given ( Fact < T > ... facts ) { for ( Fact f : facts ) { _facts . put ( f . getName ( ) , f ) ; } return this ; }


Input: The when () method accepts a { [CODESPLIT] @ Override public Rule < T > when ( Predicate < FactMap < T > > test ) { _test = test ; return this ; }


Input: The then () method accepts a { @link Consumer } that performs an action based on Facts . [CODESPLIT] @ Override @ SuppressWarnings ( "unchecked" ) public Rule < T > then ( Consumer < FactMap < T > > action ) { _actionChain . add ( action ) ; return this ; }


Input: The using () method reduces the facts to those specifically named here . The using () method only applies to the then () method immediately following it . [CODESPLIT] @ Override @ SuppressWarnings ( "unchecked" ) public StandardRule < T > using ( String ... factNames ) { List < String > factNameList = Stream . of ( factNames ) . filter ( name -> _factType . isInstance ( _facts . getValue ( name ) ) ) . collect ( Collectors . toList ( ) ) ; if ( _factNameMap . containsKey ( ( getThen ( ) ) . size ( ) ) ) { List < String > existingFactNames = _factNameMap . get ( ( getThen ( ) ) . size ( ) ) ; existingFactNames . addAll ( factNameList ) ; return this ; } _factNameMap . put ( ( getThen ( ) ) . size ( ) , factNameList ) ; return this ; }


Input: The addRule () method allows a rule to be added to the DecisionBook in the abstract defineRules method . [CODESPLIT] public void addRule ( Decision < T , U > rule ) { if ( rule == null ) { return ; } super . addRule ( rule ) ; rule . setResult ( _result ) ; }


Input: Adds a then action into the Rule . [CODESPLIT] public ThenRuleBuilder < T , U > then ( Consumer < NameValueReferableTypeConvertibleMap < T > > action ) { _rule . addAction ( action ) ; return this ; }


Input: Addds a then action into the Rule . [CODESPLIT] public ThenRuleBuilder < T , U > then ( BiConsumer < NameValueReferableTypeConvertibleMap < T > , Result < U > > action ) { _rule . addAction ( action ) ; return this ; }


Input: Specifies the default Result value . Note : RuleBooks that return a single Result must have a default Result value set . [CODESPLIT] public RuleBookDefaultResultBuilder < T > withDefaultResult ( T result ) { _ruleBook . setDefaultResult ( result ) ; return new RuleBookDefaultResultBuilder <> ( _ruleBook ) ; }


Input: Resets the value of the Result to its default value . [CODESPLIT] public void reset ( ) { _lock . readLock ( ) . lock ( ) ; try { if ( _defaultValue == null ) { return ; } } finally { _lock . readLock ( ) . unlock ( ) ; } setValue ( _defaultValue ) ; }


Input: The method getValue () returns the object contained in the Result object . [CODESPLIT] @ Override public T getValue ( ) { _lock . readLock ( ) . lock ( ) ; try { long key = Thread . currentThread ( ) . getId ( ) ; if ( _valueMap . containsKey ( key ) ) { return _valueMap . get ( Thread . currentThread ( ) . getId ( ) ) ; } return _defaultValue ; } finally { _lock . readLock ( ) . unlock ( ) ; } }


Input: The method setValue () sets the object to be contained in the Result object . [CODESPLIT] @ Override public void setValue ( T value ) { _lock . writeLock ( ) . lock ( ) ; try { _valueMap . put ( Thread . currentThread ( ) . getId ( ) , value ) ; } finally { _lock . writeLock ( ) . unlock ( ) ; } }


Input: Adds a rule to the RuleBook . [CODESPLIT] public RuleBookAddRuleBuilder < T > addRule ( Consumer < RuleBookRuleBuilder < T > > consumer ) { return new RuleBookAddRuleBuilder <> ( _ruleBook , consumer ) ; }


Input: Adds a rule to the RuleBook . [CODESPLIT] public < U > RuleBookAddRuleBuilder < T > addRule ( Rule < U , T > rule ) { return new RuleBookAddRuleBuilder <> ( _ruleBook , rule ) ; }


Input: Specifies the fact type [CODESPLIT] @ SuppressWarnings ( "unchecked" ) public < T > RuleBookRuleWithFactTypeBuilder < T , U > withFactType ( Class < T > factType ) { Rule < T , U > rule = ( Rule < T , U > ) RuleBuilder . create ( _ruleClass ) . withFactType ( factType ) . build ( ) ; _ruleBook . addRule ( rule ) ; return new RuleBookRuleWithFactTypeBuilder <> ( rule ) ; }


Input: Gets the POJO Rules to be used by the RuleBook via reflection of the specified package . [CODESPLIT] protected List < Class < ? > > getPojoRules ( ) { Reflections reflections = new Reflections ( _package ) ; List < Class < ? > > rules = reflections . getTypesAnnotatedWith ( com . deliveredtechnologies . rulebook . annotation . Rule . class ) . stream ( ) . filter ( rule -> rule . getAnnotatedSuperclass ( ) != null ) // Include classes only, exclude interfaces, etc. . filter ( rule -> _subPkgMatch . test ( rule . getPackage ( ) . getName ( ) ) ) . collect ( Collectors . toList ( ) ) ; rules . sort ( comparingInt ( aClass -> getAnnotation ( com . deliveredtechnologies . rulebook . annotation . Rule . class , aClass ) . order ( ) ) ) ; return rules ; }


Input: The combine () static method combines the contents of two arrays into a single array of the same type . [CODESPLIT] @ SuppressWarnings ( "unchecked" ) public static < T > T [ ] combine ( T [ ] array1 , T [ ] array2 ) { return combine ( array1 , array2 , array1 . length + array2 . length ) ; }


Input: The combine () static method combines the contents of two arrays into a single array of the same type that contains no more than the maxElements number of elements . [CODESPLIT] @ SuppressWarnings ( "unchecked" ) public static < T > T [ ] combine ( T [ ] array1 , T [ ] array2 , int maxElements ) { if ( array1 . length == maxElements ) { return array1 ; } else if ( array1 . length > maxElements ) { T [ ] combinedArray = ( T [ ] ) Array . newInstance ( array1 . getClass ( ) . getComponentType ( ) , maxElements ) ; System . arraycopy ( array1 , 0 , combinedArray , 0 , maxElements ) ; return combinedArray ; } maxElements = array1 . length + array2 . length >= maxElements ? maxElements : array1 . length + array2 . length ; T [ ] combinedArray = ( T [ ] ) Array . newInstance ( array1 . getClass ( ) . getComponentType ( ) , maxElements ) ; System . arraycopy ( array1 , 0 , combinedArray , 0 , array1 . length ) ; System . arraycopy ( array2 , 0 , combinedArray , array1 . length , maxElements - array1 . length ) ; return combinedArray ; }


Input: Reads empty line or throw an exception if a none empty line was found . [CODESPLIT] private String readEmptyLineOrEndTable ( final BufferedReader tableContent ) throws IOException { final String column = tableContent . readLine ( ) ; if ( column != null && column . startsWith ( END_TABLE ) ) { return END_TABLE ; } if ( column == null || ! column . isEmpty ( ) ) { throw new IllegalArgumentException ( String . format ( "Trying to read an empty line for end of row, but content %s was found or EOF" , column ) ) ; } return "" ; }


Input: Moves buffer until it finds the first content column ( skipping headers ) . [CODESPLIT] private void skipUntilColumns ( final BufferedReader tableContent ) throws IOException { String line ; while ( ( line = tableContent . readLine ( ) ) != null ) { if ( line . trim ( ) . isEmpty ( ) ) { break ; } } }


Input: =========================================================== [CODESPLIT] private ObjectMeta createDeploymentConfigMetaData ( ResourceConfig config ) { return new ObjectMetaBuilder ( ) . withName ( KubernetesHelper . validateKubernetesId ( config . getControllerName ( ) , "controller name" ) ) . build ( ) ; }


Input: ======================================================================================================= [CODESPLIT] private void addServices ( KubernetesListBuilder builder ) { ResourceConfig resources = new ResourceConfig ( ) ; if ( resources != null && resources . getServices ( ) != null ) { List < ServiceConfig > serviceConfig = resources . getServices ( ) ; ServiceHandler serviceHandler = new ServiceHandler ( ) ; builder . addToServiceItems ( toArray ( serviceHandler . getServices ( serviceConfig ) ) ) ; } }


Input: convert list to array never returns null . [CODESPLIT] private Service [ ] toArray ( List < Service > services ) { if ( services == null ) { return new Service [ 0 ] ; } if ( services instanceof ArrayList ) { return ( ( ArrayList < Service > ) services ) . toArray ( new Service [ services . size ( ) ] ) ; } else { Service [ ] ret = new Service [ services . size ( ) ] ; for ( int i = 0 ; i < services . size ( ) ; i ++ ) { ret [ i ] = services . get ( i ) ; } return ret ; } }


Input: .................................................................................... [CODESPLIT] private Map < String , String > extractLabels ( ) { Map < String , String > labels = new HashMap <> ( ) ; if ( Configs . asBoolean ( getConfig ( Config . expose ) ) ) { labels . put ( "expose" , "true" ) ; } return labels ; }


Input: Port handling [CODESPLIT] private List < ServicePort > extractPorts ( List < ImageConfiguration > images ) { List < ServicePort > ret = new ArrayList <> ( ) ; boolean isMultiPort = Boolean . parseBoolean ( getConfig ( Config . multiPort ) ) ; List < ServicePort > configuredPorts = extractPortsFromConfig ( ) ; for ( ImageConfiguration image : images ) { Map < String , String > labels = extractLabelsFromConfig ( image ) ; List < String > podPorts = getPortsFromBuildConfiguration ( image ) ; List < String > portsFromImageLabels = getLabelWithService ( labels ) ; if ( podPorts . isEmpty ( ) ) { continue ; } // Extract first port and remove first element if ( portsFromImageLabels == null || portsFromImageLabels . isEmpty ( ) ) { addPortIfNotNull ( ret , extractPortsFromImageSpec ( image . getName ( ) , podPorts . remove ( 0 ) , shiftOrNull ( configuredPorts ) , null ) ) ; } else { for ( String imageLabelPort : portsFromImageLabels ) { addPortIfNotNull ( ret , extractPortsFromImageSpec ( image . getName ( ) , podPorts . remove ( 0 ) , shiftOrNull ( configuredPorts ) , imageLabelPort ) ) ; } } // Remaining port specs if multi-port is selected if ( isMultiPort ) { for ( String port : podPorts ) { addPortIfNotNull ( ret , extractPortsFromImageSpec ( image . getName ( ) , port , shiftOrNull ( configuredPorts ) , null ) ) ; } } } // If there are still ports configured add them directly if ( isMultiPort ) { ret . addAll ( mirrorMissingTargetPorts ( configuredPorts ) ) ; } else if ( ret . isEmpty ( ) && ! configuredPorts . isEmpty ( ) ) { ret . addAll ( mirrorMissingTargetPorts ( Collections . singletonList ( configuredPorts . get ( 0 ) ) ) ) ; } return ret ; }


Input: Examine images for build configuration and extract all ports [CODESPLIT] private List < String > getPortsFromBuildConfiguration ( ImageConfiguration image ) { // No build, no default service (doesn't make much sense to have no build config, though) BuildImageConfiguration buildConfig = image . getBuildConfiguration ( ) ; if ( buildConfig == null ) { return Collections . emptyList ( ) ; } return buildConfig . getPorts ( ) ; }


Input: Config can override ports [CODESPLIT] private List < ServicePort > extractPortsFromConfig ( ) { List < ServicePort > ret = new LinkedList <> ( ) ; String ports = getConfig ( Config . port ) ; if ( ports != null ) { for ( String port : StringUtils . split ( ports , "," ) ) { ret . add ( parsePortMapping ( port ) ) ; } } return ret ; }


Input: parse config specified ports [CODESPLIT] private ServicePort parsePortMapping ( String port ) { Matcher matcher = PORT_MAPPING_PATTERN . matcher ( port ) ; if ( ! matcher . matches ( ) ) { log . error ( "Invalid 'port' configuration '%s'. Must match <port>(:<targetPort>)?,<port2>?,..." , port ) ; throw new IllegalArgumentException ( "Invalid port mapping specification " + port ) ; } int servicePort = Integer . parseInt ( matcher . group ( "port" ) ) ; String optionalTargetPort = matcher . group ( "targetPort" ) ; String protocol = getProtocol ( matcher . group ( "protocol" ) ) ; ServicePortBuilder builder = new ServicePortBuilder ( ) . withPort ( servicePort ) . withProtocol ( protocol ) . withName ( getDefaultPortName ( servicePort , protocol ) ) ; // leave empty if not set. will be filled up with the port from the image config if ( optionalTargetPort != null ) { builder . withNewTargetPort ( Integer . parseInt ( optionalTargetPort ) ) ; } return builder . build ( ) ; }


Input: null ports can happen for ignored mappings [CODESPLIT] private void addPortIfNotNull ( List < ServicePort > ret , ServicePort port ) { if ( port != null ) { ret . add ( port ) ; } }


Input: remove first element of list or null if list is empty [CODESPLIT] private ServicePort shiftOrNull ( List < ServicePort > ports ) { if ( ! ports . isEmpty ( ) ) { return ports . remove ( 0 ) ; } return null ; }


Input: ------------------------- [CODESPLIT] private String getDefaultServiceName ( Service defaultService ) { String defaultServiceName = KubernetesHelper . getName ( defaultService ) ; if ( StringUtils . isBlank ( defaultServiceName ) ) { defaultServiceName = getContext ( ) . getGav ( ) . getSanitizedArtifactId ( ) ; } return defaultServiceName ; }


Input: Merge services of same name with the default service [CODESPLIT] private void addMissingServiceParts ( ServiceBuilder service , Service defaultService ) { // If service has no spec -> take over the complete spec from default service if ( ! service . hasSpec ( ) ) { service . withNewSpecLike ( defaultService . getSpec ( ) ) . endSpec ( ) ; return ; } // If service has no ports -> take over ports from default service List < ServicePort > ports = service . buildSpec ( ) . getPorts ( ) ; if ( ports == null || ports . isEmpty ( ) ) { service . editSpec ( ) . withPorts ( defaultService . getSpec ( ) . getPorts ( ) ) . endSpec ( ) ; return ; } // Complete missing parts: service . editSpec ( ) . withPorts ( addMissingDefaultPorts ( ports , defaultService ) ) . endSpec ( ) ; }


Input: Save the images stream to a file [CODESPLIT] public void appendImageStreamResource ( ImageName imageName , File target ) throws MojoExecutionException { String tag = StringUtils . isBlank ( imageName . getTag ( ) ) ? "latest" : imageName . getTag ( ) ; try { ImageStream is = new ImageStreamBuilder ( ) . withNewMetadata ( ) . withName ( imageName . getSimpleName ( ) ) . endMetadata ( ) . withNewSpec ( ) . addNewTag ( ) . withName ( tag ) . withNewFrom ( ) . withKind ( "ImageStreamImage" ) . endFrom ( ) . endTag ( ) . endSpec ( ) . build ( ) ; createOrUpdateImageStreamTag ( client , imageName , is ) ; appendImageStreamToFile ( is , target ) ; log . info ( "ImageStream %s written to %s" , imageName . getSimpleName ( ) , target ) ; } catch ( KubernetesClientException e ) { KubernetesResourceUtil . handleKubernetesClientException ( e , this . log ) ; } catch ( IOException e ) { throw new MojoExecutionException ( String . format ( "Cannot write ImageStream descriptor for %s to %s : %s" , imageName . getFullName ( ) , target . getAbsoluteFile ( ) , e . getMessage ( ) ) , e ) ; } }


Input: Returns the URL to access the service ; using the environment variables routes or service clusterIP address [CODESPLIT] public static String getServiceURL ( KubernetesClient client , String serviceName , String serviceNamespace , String serviceProtocol , boolean serviceExternal ) { Service srv = null ; String serviceHost = serviceToHostOrBlank ( serviceName ) ; String servicePort = serviceToPortOrBlank ( serviceName ) ; String serviceProto = serviceProtocol != null ? serviceProtocol : serviceToProtocol ( serviceName , servicePort ) ; //Use specified or fallback namespace. String actualNamespace = StringUtils . isNotBlank ( serviceNamespace ) ? serviceNamespace : client . getNamespace ( ) ; //1. Inside Kubernetes: Services as ENV vars if ( ! serviceExternal && StringUtils . isNotBlank ( serviceHost ) && StringUtils . isNotBlank ( servicePort ) && StringUtils . isNotBlank ( serviceProtocol ) ) { return serviceProtocol + "://" + serviceHost + ":" + servicePort ; //2. Anywhere: When namespace is passed System / Env var. Mostly needed for integration tests. } else if ( StringUtils . isNotBlank ( actualNamespace ) ) { srv = client . services ( ) . inNamespace ( actualNamespace ) . withName ( serviceName ) . get ( ) ; } if ( srv == null ) { // lets try use environment variables String hostAndPort = getServiceHostAndPort ( serviceName , "" , "" ) ; if ( ! hostAndPort . startsWith ( ":" ) ) { return serviceProto + "://" + hostAndPort ; } } if ( srv == null ) { throw new IllegalArgumentException ( "No kubernetes service could be found for name: " + serviceName + " in namespace: " + actualNamespace ) ; } String answer = KubernetesHelper . getOrCreateAnnotations ( srv ) . get ( Fabric8Annotations . SERVICE_EXPOSE_URL . toString ( ) ) ; if ( StringUtils . isNotBlank ( answer ) ) { return answer ; } if ( OpenshiftHelper . isOpenShift ( client ) ) { OpenShiftClient openShiftClient = client . adapt ( OpenShiftClient . class ) ; Route route = openShiftClient . routes ( ) . inNamespace ( actualNamespace ) . withName ( serviceName ) . get ( ) ; if ( route != null ) { return ( serviceProto + "://" + route . getSpec ( ) . getHost ( ) ) . toLowerCase ( ) ; } } ServicePort port = findServicePortByName ( srv , null ) ; if ( port == null ) { throw new RuntimeException ( "Couldn't find port: " + null + " for service:" + serviceName ) ; } String clusterIP = srv . getSpec ( ) . getClusterIP ( ) ; if ( "None" . equals ( clusterIP ) ) { throw new IllegalStateException ( "Service: " + serviceName + " in namespace:" + serviceNamespace + "is head-less. Search for endpoints instead." ) ; } Integer portNumber = port . getPort ( ) ; if ( StringUtils . isBlank ( clusterIP ) ) { IngressList ingresses = client . extensions ( ) . ingresses ( ) . inNamespace ( serviceNamespace ) . list ( ) ; if ( ingresses != null ) { List < Ingress > items = ingresses . getItems ( ) ; if ( items != null ) { for ( Ingress item : items ) { String ns = KubernetesHelper . getNamespace ( item ) ; if ( Objects . equal ( serviceNamespace , ns ) ) { IngressSpec spec = item . getSpec ( ) ; if ( spec != null ) { List < IngressRule > rules = spec . getRules ( ) ; List < IngressTLS > tls = spec . getTls ( ) ; if ( rules != null ) { for ( IngressRule rule : rules ) { HTTPIngressRuleValue http = rule . getHttp ( ) ; if ( http != null ) { List < HTTPIngressPath > paths = http . getPaths ( ) ; if ( paths != null ) { for ( HTTPIngressPath path : paths ) { IngressBackend backend = path . getBackend ( ) ; if ( backend != null ) { String backendServiceName = backend . getServiceName ( ) ; if ( serviceName . equals ( backendServiceName ) && portsMatch ( port , backend . getServicePort ( ) ) ) { String pathPostfix = path . getPath ( ) ; if ( tls != null ) { for ( IngressTLS tlsHost : tls ) { List < String > hosts = tlsHost . getHosts ( ) ; if ( hosts != null ) { for ( String host : hosts ) { if ( StringUtils . isNotBlank ( host ) ) { return String . format ( "https://%s/%s" , host , preparePath ( pathPostfix ) ) ; } } } } } answer = rule . getHost ( ) ; if ( StringUtils . isNotBlank ( answer ) ) { return String . format ( "http://%s/%s" , answer , preparePath ( pathPostfix ) ) ; } } } } } } } } } } } } } // lets try use the status on GKE ServiceStatus status = srv . getStatus ( ) ; if ( status != null ) { LoadBalancerStatus loadBalancerStatus = status . getLoadBalancer ( ) ; if ( loadBalancerStatus != null ) { List < LoadBalancerIngress > loadBalancerIngresses = loadBalancerStatus . getIngress ( ) ; if ( loadBalancerIngresses != null ) { for ( LoadBalancerIngress loadBalancerIngress : loadBalancerIngresses ) { String ip = loadBalancerIngress . getIp ( ) ; if ( StringUtils . isNotBlank ( ip ) ) { clusterIP = ip ; break ; } } } } } } if ( StringUtils . isBlank ( clusterIP ) ) { // on vanilla kubernetes we can use nodePort to access things externally boolean found = false ; Integer nodePort = port . getNodePort ( ) ; if ( nodePort != null ) { NodeList nodeList = client . nodes ( ) . list ( ) ; if ( nodeList != null ) { List < Node > items = nodeList . getItems ( ) ; if ( items != null ) { for ( Node item : items ) { NodeStatus status = item . getStatus ( ) ; if ( ! found && status != null ) { List < NodeAddress > addresses = status . getAddresses ( ) ; if ( addresses != null ) { for ( NodeAddress address : addresses ) { String ip = address . getAddress ( ) ; if ( StringUtils . isNotBlank ( ip ) ) { clusterIP = ip ; portNumber = nodePort ; found = true ; break ; } } } } if ( ! found ) { NodeSpec spec = item . getSpec ( ) ; if ( spec != null ) { clusterIP = spec . getExternalID ( ) ; if ( StringUtils . isNotBlank ( clusterIP ) ) { portNumber = nodePort ; break ; } } } } } } } } return ( serviceProto + "://" + clusterIP + ":" + portNumber ) . toLowerCase ( ) ; }


Input: Returns true if the given servicePort matches the intOrString value [CODESPLIT] private static boolean portsMatch ( ServicePort servicePort , IntOrString intOrString ) { if ( intOrString != null ) { Integer port = servicePort . getPort ( ) ; Integer intVal = intOrString . getIntVal ( ) ; String strVal = intOrString . getStrVal ( ) ; if ( intVal != null ) { if ( port != null ) { return port . intValue ( ) == intVal . intValue ( ) ; } else { /// should we find the port by name now? } } else if ( strVal != null ) { return Objects . equal ( strVal , servicePort . getName ( ) ) ; } } return false ; }


Input: Returns the named port for the given service name or blank [CODESPLIT] private static String serviceToPortOrBlank ( String serviceName ) { String envVarName = toServicePortEnvironmentVariable ( serviceName ) ; return getEnvVarOrSystemProperty ( envVarName , "" ) ; }


Input: Returns the service host and port for the given environment variable name . [CODESPLIT] private static String getServiceHostAndPort ( String serviceName , String defaultHost , String defaultPort ) { String serviceEnvVarPrefix = getServiceEnvVarPrefix ( serviceName ) ; String hostEnvVar = serviceEnvVarPrefix + "_HOST" ; String portEnvVar = serviceEnvVarPrefix + "_PORT" ; String host = getEnvVarOrSystemProperty ( hostEnvVar , hostEnvVar , defaultHost ) ; String port = getEnvVarOrSystemProperty ( portEnvVar , portEnvVar , defaultPort ) ; String answer = host + ":" + port ; return answer ; }


Input: Adds the given key and value pair into the map if the map does not already contain a value for that key [CODESPLIT] public static void putIfAbsent ( Map < String , String > map , String name , String value ) { if ( ! map . containsKey ( name ) ) { map . put ( name , value ) ; } }


Input: Add all values of a map to another map but onlfy if not already existing . [CODESPLIT] public static void mergeIfAbsent ( Map < String , String > map , Map < String , String > toMerge ) { for ( Map . Entry < String , String > entry : toMerge . entrySet ( ) ) { putIfAbsent ( map , entry . getKey ( ) , entry . getValue ( ) ) ; ; } }


Input: Returns a new map with all the entries of map1 and any from map2 which don t override map1 . [CODESPLIT] public static < K , V > Map < K , V > mergeMaps ( Map < K , V > map1 , Map < K , V > map2 ) { Map < K , V > answer = new HashMap <> ( ) ; if ( map2 != null ) { answer . putAll ( map2 ) ; } if ( map1 != null ) { answer . putAll ( map1 ) ; } return answer ; }


Input: Copies all of the elements i . e . the mappings from toPut map into ret if toPut isn t null . [CODESPLIT] public static void putAllIfNotNull ( Map < String , String > ret , Map < String , String > toPut ) { if ( toPut != null ) { ret . putAll ( toPut ) ; } }


Input: ============================================================================================================ [CODESPLIT] private void ensureTemplateSpecs ( KubernetesListBuilder builder ) { ensureTemplateSpecsInReplicationControllers ( builder ) ; ensureTemplateSpecsInRelicaSet ( builder ) ; ensureTemplateSpecsInDeployments ( builder ) ; ensureTemplateSpecsInDaemonSet ( builder ) ; ensureTemplateSpecsInStatefulSet ( builder ) ; ensureTemplateSpecsInDeploymentConfig ( builder ) ; }


Input: ============================================================================================================ [CODESPLIT] private void updateContainers ( KubernetesListBuilder builder ) { builder . accept ( new TypedVisitor < PodTemplateSpecBuilder > ( ) { @ Override public void visit ( PodTemplateSpecBuilder templateBuilder ) { PodTemplateSpecFluent . SpecNested < PodTemplateSpecBuilder > podSpec = templateBuilder . getSpec ( ) == null ? templateBuilder . withNewSpec ( ) : templateBuilder . editSpec ( ) ; List < Container > containers = podSpec . getContainers ( ) ; if ( containers == null ) { containers = new ArrayList < Container > ( ) ; } mergeImageConfigurationWithContainerSpec ( containers ) ; podSpec . withContainers ( containers ) . endSpec ( ) ; } } ) ; }


Input: configured [CODESPLIT] private void mergeImageConfigurationWithContainerSpec ( List < Container > containers ) { getImages ( ) . ifPresent ( images -> { int idx = 0 ; for ( ImageConfiguration image : images ) { Container container = getContainer ( idx , containers ) ; mergeImagePullPolicy ( image , container ) ; mergeImage ( image , container ) ; mergeContainerName ( image , container ) ; mergeEnvVariables ( container ) ; idx ++ ; } } ) ; }


Input: A Simple utility function to watch over pod until it gets ready [CODESPLIT] private void waitUntilPodIsReady ( String podName , int nAwaitTimeout , final Logger log ) throws InterruptedException { final CountDownLatch readyLatch = new CountDownLatch ( 1 ) ; try ( Watch watch = client . pods ( ) . withName ( podName ) . watch ( new Watcher < Pod > ( ) { @ Override public void eventReceived ( Action action , Pod aPod ) { if ( KubernetesHelper . isPodReady ( aPod ) ) { readyLatch . countDown ( ) ; } } @ Override public void onClose ( KubernetesClientException e ) { // Ignore } } ) ) { readyLatch . await ( nAwaitTimeout , TimeUnit . SECONDS ) ; } catch ( KubernetesClientException | InterruptedException e ) { log . error ( "Could not watch pod" , e ) ; } }


Input: == Utility methods ========================== [CODESPLIT] private String getS2IBuildName ( BuildServiceConfig config , ImageName imageName ) { return imageName . getSimpleName ( ) + config . getS2iBuildNameSuffix ( ) ; }


Input: ================= [CODESPLIT] private static EntityPatcher < BuildConfig > bcPatcher ( ) { return ( KubernetesClient client , String namespace , BuildConfig newObj , BuildConfig oldObj ) -> { if ( UserConfigurationCompare . configEqual ( newObj , oldObj ) ) { return oldObj ; } OpenShiftClient openShiftClient = OpenshiftHelper . asOpenShiftClient ( client ) ; if ( openShiftClient == null ) { throw new IllegalArgumentException ( "BuildConfig can only be patched when connected to an OpenShift cluster" ) ; } DoneableBuildConfig entity = openShiftClient . buildConfigs ( ) . inNamespace ( namespace ) . withName ( oldObj . getMetadata ( ) . getName ( ) ) . edit ( ) ; if ( ! UserConfigurationCompare . configEqual ( newObj . getMetadata ( ) , oldObj . getMetadata ( ) ) ) { entity . withMetadata ( newObj . getMetadata ( ) ) ; } if ( ! UserConfigurationCompare . configEqual ( newObj . getSpec ( ) , oldObj . getSpec ( ) ) ) { entity . withSpec ( newObj . getSpec ( ) ) ; } return entity . done ( ) ; } ; }


Input: Validates that the given value is valid according to the kubernetes ID parsing rules throwing an exception if not . [CODESPLIT] public static String validateKubernetesId ( String currentValue , String description ) throws IllegalArgumentException { if ( StringUtils . isBlank ( currentValue ) ) { throw new IllegalArgumentException ( "No " + description + " is specified!" ) ; } int size = currentValue . length ( ) ; for ( int i = 0 ; i < size ; i ++ ) { char ch = currentValue . charAt ( i ) ; if ( Character . isUpperCase ( ch ) ) { throw new IllegalArgumentException ( "Invalid upper case letter '" + ch + "' at index " + i + " for " + description + " value: " + currentValue ) ; } } return currentValue ; }


Input: Loads the Kubernetes JSON and converts it to a list of entities [CODESPLIT] @ SuppressWarnings ( "unchecked" ) public static List < HasMetadata > toItemList ( Object entity ) throws IOException { if ( entity instanceof List ) { return ( List < HasMetadata > ) entity ; } else if ( entity instanceof HasMetadata [ ] ) { HasMetadata [ ] array = ( HasMetadata [ ] ) entity ; return Arrays . asList ( array ) ; } else if ( entity instanceof KubernetesList ) { KubernetesList config = ( KubernetesList ) entity ; return config . getItems ( ) ; } else if ( entity instanceof Template ) { Template objects = ( Template ) entity ; return objects . getObjects ( ) ; } else { List < HasMetadata > answer = new ArrayList <> ( ) ; if ( entity instanceof HasMetadata ) { answer . add ( ( HasMetadata ) entity ) ; } return answer ; } }


Input: Returns the resource version for the entity or null if it does not have one [CODESPLIT] public static String getResourceVersion ( HasMetadata entity ) { if ( entity != null ) { ObjectMeta metadata = entity . getMetadata ( ) ; if ( metadata != null ) { String resourceVersion = metadata . getResourceVersion ( ) ; if ( StringUtils . isNotBlank ( resourceVersion ) ) { return resourceVersion ; } } } return null ; }


Input: Creates an IntOrString from the given string which could be a number or a name [CODESPLIT] public static IntOrString createIntOrString ( int intVal ) { IntOrString answer = new IntOrString ( ) ; answer . setIntVal ( intVal ) ; answer . setKind ( 0 ) ; return answer ; }


Input: Creates an IntOrString from the given string which could be a number or a name [CODESPLIT] public static IntOrString createIntOrString ( String nameOrNumber ) { if ( StringUtils . isBlank ( nameOrNumber ) ) { return null ; } else { IntOrString answer = new IntOrString ( ) ; Integer intVal = null ; try { intVal = Integer . parseInt ( nameOrNumber ) ; } catch ( Exception e ) { // ignore invalid number } if ( intVal != null ) { answer . setIntVal ( intVal ) ; answer . setKind ( 0 ) ; } else { answer . setStrVal ( nameOrNumber ) ; answer . setKind ( 1 ) ; } return answer ; } }


Input: Returns true if the pod is running and ready [CODESPLIT] public static boolean isPodReady ( Pod pod ) { if ( ! isPodRunning ( pod ) ) { return false ; } PodStatus podStatus = pod . getStatus ( ) ; if ( podStatus == null ) { return true ; } List < PodCondition > conditions = podStatus . getConditions ( ) ; if ( conditions == null || conditions . isEmpty ( ) ) { return true ; } // Check "ready" condition for ( PodCondition condition : conditions ) { if ( "ready" . equalsIgnoreCase ( condition . getType ( ) ) ) { return Boolean . parseBoolean ( condition . getStatus ( ) ) ; } } return true ; }


Input: Returns the current context in the given config [CODESPLIT] private static Context getCurrentContext ( Config config ) { String contextName = config . getCurrentContext ( ) ; if ( contextName != null ) { List < NamedContext > contexts = config . getContexts ( ) ; if ( contexts != null ) { for ( NamedContext context : contexts ) { if ( Objects . equals ( contextName , context . getName ( ) ) ) { return context . getContext ( ) ; } } } } return null ; }


Input: Returns true if we already have a route created for the given name [CODESPLIT] private boolean hasRoute ( final KubernetesListBuilder listBuilder , final String name ) { final AtomicBoolean answer = new AtomicBoolean ( false ) ; listBuilder . accept ( new TypedVisitor < RouteBuilder > ( ) { @ Override public void visit ( RouteBuilder builder ) { ObjectMeta metadata = builder . getMetadata ( ) ; if ( metadata != null && name . equals ( metadata . getName ( ) ) ) { answer . set ( true ) ; } } } ) ; return answer . get ( ) ; }


Input: Replaces all text of the form <code > $ { foo } < / code > with the value in the properties object [CODESPLIT] protected static String replaceProperties ( String text , Properties properties ) { Set < Map . Entry < Object , Object > > entries = properties . entrySet ( ) ; for ( Map . Entry < Object , Object > entry : entries ) { Object key = entry . getKey ( ) ; Object value = entry . getValue ( ) ; if ( key != null && value != null ) { String pattern = "${" + key + "}" ; text = StringUtils . replace ( text , pattern , value . toString ( ) ) ; } } return text ; }


Input:
========================================================================================================== [CODESPLIT] private static void addShutdownHook ( final Logger log , final Process process , final File command ) { Runtime . getRuntime ( ) . addShutdownHook ( new Thread ( command . getName ( ) ) { @ Override public void run ( ) { if ( process != null ) { // Trying to determine if the process is alive boolean alive = false ; try { process . exitValue ( ) ; } catch ( IllegalThreadStateException e ) { alive = true ; } if ( alive ) { log . info ( "Terminating process %s" , command ) ; try { process . destroy ( ) ; } catch ( Exception e ) { log . error ( "Failed to terminate process %s" , command ) ; } /* Only available in Java 8: So disabled for now until we switch to Java 8
                        try {
                            if (process != null && process.isAlive()) {
                                process.destroyForcibly();
                            }
                        } catch (Exception e) {
                            log.error("Failed to forcibly terminate process %s", command);
                        }
                        */ } } } } ) ; }


Input: Forwards a port to the newest pod matching the given selector . If another pod is created it forwards connections to the new pod once it s ready . [CODESPLIT] public Closeable forwardPortAsync ( final Logger externalProcessLogger , final LabelSelector podSelector , final int remotePort , final int localPort ) throws Fabric8ServiceException { final Lock monitor = new ReentrantLock ( true ) ; final Condition podChanged = monitor . newCondition ( ) ; final Pod [ ] nextForwardedPod = new Pod [ 1 ] ; final Thread forwarderThread = new Thread ( ) { @ Override public void run ( ) { Pod currentPod = null ; Closeable currentPortForward = null ; try { monitor . lock ( ) ; while ( true ) { if ( podEquals ( currentPod , nextForwardedPod [ 0 ] ) ) { podChanged . await ( ) ; } else { Pod nextPod = nextForwardedPod [ 0 ] ; // may be null try { monitor . unlock ( ) ; // out of critical section if ( currentPortForward != null ) { log . info ( "Closing port-forward from pod %s" , KubernetesHelper . getName ( currentPod ) ) ; currentPortForward . close ( ) ; currentPortForward = null ; } if ( nextPod != null ) { log . info ( "Starting port-forward to pod %s" , KubernetesHelper . getName ( nextPod ) ) ; currentPortForward = forwardPortAsync ( externalProcessLogger , KubernetesHelper . getName ( nextPod ) , remotePort , localPort ) ; } else { log . info ( "Waiting for a pod to become ready before starting port-forward" ) ; } currentPod = nextPod ; } finally { monitor . lock ( ) ; } } } } catch ( InterruptedException e ) { log . debug ( "Port-forwarding thread interrupted" , e ) ; Thread . currentThread ( ) . interrupt ( ) ; } catch ( Exception e ) { log . warn ( "Error while port-forwarding to pod" , e ) ; } finally { monitor . unlock ( ) ; if ( currentPortForward != null ) { try { currentPortForward . close ( ) ; } catch ( Exception e ) { } } } } } ; // Switching forward to the current pod if present Pod newPod = getNewestPod ( podSelector ) ; nextForwardedPod [ 0 ] = newPod ; final Watch watch = KubernetesClientUtil . withSelector ( kubernetes . pods ( ) , podSelector , log ) . watch ( new Watcher < Pod > ( ) { @ Override public void eventReceived ( Action action , Pod pod ) { monitor . lock ( ) ; try { List < Pod > candidatePods ; if ( nextForwardedPod [ 0 ] != null ) { candidatePods = new LinkedList <> ( ) ; candidatePods . add ( nextForwardedPod [ 0 ] ) ; candidatePods . add ( pod ) ; } else { candidatePods = Collections . singletonList ( pod ) ; } Pod newPod = getNewestPod ( candidatePods ) ; // may be null if ( ! podEquals ( nextForwardedPod [ 0 ] , newPod ) ) { nextForwardedPod [ 0 ] = newPod ; podChanged . signal ( ) ; } } finally { monitor . unlock ( ) ; } } @ Override public void onClose ( KubernetesClientException e ) { // don't care } } ) ; forwarderThread . start ( ) ; final Closeable handle = ( ) -> { try { watch . close ( ) ; } catch ( Exception e ) { } try { forwarderThread . interrupt ( ) ; forwarderThread . join ( 15000 ) ; } catch ( Exception e ) { } } ; Runtime . getRuntime ( ) . addShutdownHook ( new Thread ( ) { @ Override public void run ( ) { try { handle . close ( ) ; } catch ( Exception e ) { // suppress } } } ) ; return handle ; }


Input: ==================================================== [CODESPLIT] private static URLClassLoader createClassLoader ( List < String > classpathElements , String ... paths ) { List < URL > urls = new ArrayList <> ( ) ; for ( String path : paths ) { URL url = pathToUrl ( path ) ; urls . add ( url ) ; } for ( Object object : classpathElements ) { if ( object != null ) { String path = object . toString ( ) ; URL url = pathToUrl ( path ) ; urls . add ( url ) ; } } return createURLClassLoader ( urls ) ; }


Input: Returns true if the maven project has a dependency with the given groupId and artifactId ( if not null ) [CODESPLIT] public static boolean hasDependency ( MavenProject project , String groupId , String artifactId ) { return getDependencyVersion ( project , groupId , artifactId ) != null ; }


Input: Returns the version associated to the dependency dependency with the given groupId and artifactId ( if present ) [CODESPLIT] public static String getDependencyVersion ( MavenProject project , String groupId , String artifactId ) { Set < Artifact > artifacts = project . getArtifacts ( ) ; if ( artifacts != null ) { for ( Artifact artifact : artifacts ) { String scope = artifact . getScope ( ) ; if ( Objects . equal ( "test" , scope ) ) { continue ; } if ( artifactId != null && ! Objects . equal ( artifactId , artifact . getArtifactId ( ) ) ) { continue ; } if ( Objects . equal ( groupId , artifact . getGroupId ( ) ) ) { return artifact . getVersion ( ) ; } } } return null ; }


Input: Returns the plugin with the given groupId ( if present ) and artifactId . [CODESPLIT] public static Plugin getPlugin ( MavenProject project , String groupId , String artifactId ) { if ( artifactId == null ) { throw new IllegalArgumentException ( "artifactId cannot be null" ) ; } List < Plugin > plugins = project . getBuildPlugins ( ) ; if ( plugins != null ) { for ( Plugin plugin : plugins ) { boolean matchesArtifactId = artifactId . equals ( plugin . getArtifactId ( ) ) ; boolean matchesGroupId = groupId == null || groupId . equals ( plugin . getGroupId ( ) ) ; if ( matchesGroupId && matchesArtifactId ) { return plugin ; } } } return null ; }


Input: Returns true if any of the given resources could be found on the given class loader [CODESPLIT] public static boolean hasResource ( MavenProject project , String ... paths ) { URLClassLoader compileClassLoader = getCompileClassLoader ( project ) ; for ( String path : paths ) { try { if ( compileClassLoader . getResource ( path ) != null ) { return true ; } } catch ( Throwable e ) { // ignore } } return false ; }


Input: Returns the version from the list of pre - configured versions of common groupId / artifact pairs [CODESPLIT] public static String getVersion ( String groupId , String artifactId ) throws IOException { String path = "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties" ; InputStream in = MavenUtil . class . getClassLoader ( ) . getResourceAsStream ( path ) ; if ( in == null ) { throw new IOException ( "Could not find " + path + " on classath!" ) ; } Properties properties = new Properties ( ) ; try { properties . load ( in ) ; } catch ( IOException e ) { throw new IOException ( "Failed to load " + path + ". " + e , e ) ; } String version = properties . getProperty ( "version" ) ; if ( StringUtils . isBlank ( version ) ) { throw new IOException ( "No version property in " + path ) ; } return version ; }


Input: Returns true if this cluster is a traditional OpenShift cluster with the <code > / oapi< / code > REST API or supports the new <code > / apis / image . openshift . io< / code > API Group [CODESPLIT] public boolean isOpenShiftImageStream ( Logger log ) { if ( isOpenShift ( log ) ) { OpenShiftClient openShiftClient = null ; if ( this . client == null ) { openShiftClient = createOpenShiftClient ( ) ; } else if ( this . client instanceof OpenShiftClient ) { openShiftClient = ( OpenShiftClient ) this . client ; } else if ( this . client . isAdaptable ( OpenShiftClient . class ) ) { openShiftClient = client . adapt ( OpenShiftClient . class ) ; } else { return false ; } return openShiftClient . supportsOpenShiftAPIGroup ( OpenShiftAPIGroups . IMAGE ) ; } return false ; }


Input: Read all Kubernetes resource fragments from a directory and create a { @link KubernetesListBuilder } which can be adapted later . [CODESPLIT] public static KubernetesListBuilder readResourceFragmentsFrom ( PlatformMode platformMode , ResourceVersioning apiVersions , String defaultName , File [ ] resourceFiles ) throws IOException { KubernetesListBuilder builder = new KubernetesListBuilder ( ) ; if ( resourceFiles != null ) { for ( File file : resourceFiles ) { HasMetadata resource = getResource ( platformMode , apiVersions , file , defaultName ) ; builder . addToItems ( resource ) ; } } return builder ; }


Input: Read a Kubernetes resource fragment and add meta information extracted from the filename to the resource descriptor . I . e . the following elements are added if not provided in the fragment : [CODESPLIT] public static HasMetadata getResource ( PlatformMode platformMode , ResourceVersioning apiVersions , File file , String appName ) throws IOException { Map < String , Object > fragment = readAndEnrichFragment ( platformMode , apiVersions , file , appName ) ; ObjectMapper mapper = new ObjectMapper ( ) ; try { return mapper . convertValue ( fragment , HasMetadata . class ) ; } catch ( ClassCastException exp ) { throw new IllegalArgumentException ( String . format ( "Resource fragment %s has an invalid syntax (%s)" , file . getPath ( ) , exp . getMessage ( ) ) ) ; } }


Input: Read fragment and add default values [CODESPLIT] private static Map < String , Object > readAndEnrichFragment ( PlatformMode platformMode , ResourceVersioning apiVersions , File file , String appName ) throws IOException { Pattern pattern = Pattern . compile ( FILENAME_PATTERN , Pattern . CASE_INSENSITIVE ) ; Matcher matcher = pattern . matcher ( file . getName ( ) ) ; if ( ! matcher . matches ( ) ) { throw new IllegalArgumentException ( String . format ( "Resource file name '%s' does not match pattern <name>-<type>.(yaml|yml|json)" , file . getName ( ) ) ) ; } String name = matcher . group ( "name" ) ; String type = matcher . group ( "type" ) ; String ext = matcher . group ( "ext" ) . toLowerCase ( ) ; String kind ; Map < String , Object > fragment = readFragment ( file , ext ) ; if ( type != null ) { kind = getAndValidateKindFromType ( file , type ) ; } else { // Try name as type kind = FILENAME_TO_KIND_MAPPER . get ( name . toLowerCase ( ) ) ; if ( kind != null ) { // Name is in fact the type, so lets erase the name. name = null ; } } addKind ( fragment , kind , file . getName ( ) ) ; String apiVersion = apiVersions . getCoreVersion ( ) ; if ( Objects . equals ( kind , "Ingress" ) ) { apiVersion = apiVersions . getExtensionsVersion ( ) ; } else if ( Objects . equals ( kind , "StatefulSet" ) || Objects . equals ( kind , "Deployment" ) ) { apiVersion = apiVersions . getAppsVersion ( ) ; } else if ( Objects . equals ( kind , "Job" ) ) { apiVersion = apiVersions . getJobVersion ( ) ; } else if ( Objects . equals ( kind , "DeploymentConfig" ) && platformMode == PlatformMode . openshift ) { apiVersion = apiVersions . getOpenshiftV1version ( ) ; } addIfNotExistent ( fragment , "apiVersion" , apiVersion ) ; Map < String , Object > metaMap = getMetadata ( fragment ) ; // No name means: generated app name should be taken as resource name addIfNotExistent ( metaMap , "name" , StringUtils . isNotBlank ( name ) ? name : appName ) ; return fragment ; }


Input: =============================================================================================== [CODESPLIT] private static Map < String , Object > getMetadata ( Map < String , Object > fragment ) { Object mo = fragment . get ( "metadata" ) ; Map < String , Object > meta ; if ( mo == null ) { meta = new HashMap <> ( ) ; fragment . put ( "metadata" , meta ) ; return meta ; } else if ( mo instanceof Map ) { return ( Map < String , Object > ) mo ; } else { throw new IllegalArgumentException ( "Metadata is expected to be a Map, not a " + mo . getClass ( ) ) ; } }


Input: Convert a map of env vars to a list of K8s EnvVar objects . [CODESPLIT] public static List < EnvVar > convertToEnvVarList ( Map < String , String > envVars ) { List < EnvVar > envList = new LinkedList <> ( ) ; for ( Map . Entry < String , String > entry : envVars . entrySet ( ) ) { String name = entry . getKey ( ) ; String value = entry . getValue ( ) ; if ( name != null ) { EnvVar env = new EnvVarBuilder ( ) . withName ( name ) . withValue ( value ) . build ( ) ; envList . add ( env ) ; } } return envList ; }


Input: Uses reflection to copy over default values from the defaultValues object to the targetValues object similar to the following : [CODESPLIT] public static void mergeSimpleFields ( Object targetValues , Object defaultValues ) { Class < ? > tc = targetValues . getClass ( ) ; Class < ? > sc = defaultValues . getClass ( ) ; for ( Method targetGetMethod : tc . getMethods ( ) ) { if ( ! targetGetMethod . getName ( ) . startsWith ( "get" ) ) { continue ; } Class < ? > fieldType = targetGetMethod . getReturnType ( ) ; if ( ! SIMPLE_FIELD_TYPES . contains ( fieldType ) ) { continue ; } String fieldName = targetGetMethod . getName ( ) . substring ( 3 ) ; Method withMethod = null ; try { withMethod = tc . getMethod ( "with" + fieldName , fieldType ) ; } catch ( NoSuchMethodException e ) { try { withMethod = tc . getMethod ( "set" + fieldName , fieldType ) ; } catch ( NoSuchMethodException e2 ) { continue ; } } Method sourceGetMethod = null ; try { sourceGetMethod = sc . getMethod ( "get" + fieldName ) ; } catch ( NoSuchMethodException e ) { continue ; } try { if ( targetGetMethod . invoke ( targetValues ) == null ) { withMethod . invoke ( targetValues , sourceGetMethod . invoke ( defaultValues ) ) ; } } catch ( IllegalAccessException e ) { throw new RuntimeException ( e ) ; } catch ( InvocationTargetException e ) { throw new RuntimeException ( e . getCause ( ) ) ; } } }


Input: Merges the given resources together into a single resource . [CODESPLIT] public static HasMetadata mergeResources ( HasMetadata item1 , HasMetadata item2 , Logger log , boolean switchOnLocalCustomisation ) { if ( item1 instanceof Deployment && item2 instanceof Deployment ) { return mergeDeployments ( ( Deployment ) item1 , ( Deployment ) item2 , log , switchOnLocalCustomisation ) ; } if ( item1 instanceof ConfigMap && item2 instanceof ConfigMap ) { ConfigMap cm1 = ( ConfigMap ) item1 ; ConfigMap cm2 = ( ConfigMap ) item2 ; return mergeConfigMaps ( cm1 , cm2 , log , switchOnLocalCustomisation ) ; } mergeMetadata ( item1 , item2 ) ; return item1 ; }


Input: Returns a merge of the given maps and then removes any resulting empty string values ( which is the way to remove say a label or annotation when overriding [CODESPLIT] private static Map < String , String > mergeMapsAndRemoveEmptyStrings ( Map < String , String > overrideMap , Map < String , String > originalMap ) { Map < String , String > answer = MapUtil . mergeMaps ( overrideMap , originalMap ) ; Set < Map . Entry < String , String > > entries = overrideMap . entrySet ( ) ; for ( Map . Entry < String , String > entry : entries ) { String value = entry . getValue ( ) ; if ( value == null || value . isEmpty ( ) ) { String key = entry . getKey ( ) ; answer . remove ( key ) ; } } return answer ; }


Input: we could also use an annotation? [CODESPLIT] private static boolean isLocalCustomisation ( PodSpec podSpec ) { List < Container > containers = podSpec . getContainers ( ) != null ? podSpec . getContainers ( ) : Collections . < Container > emptyList ( ) ; for ( Container container : containers ) { if ( StringUtils . isNotBlank ( container . getImage ( ) ) ) { return false ; } } return true ; }


Input: Reads the configuration from the file . [CODESPLIT] private Map < String , String > readConfig ( File f ) throws IOException { Map < String , String > map ; if ( f . getName ( ) . endsWith ( JSON_EXTENSION ) ) { map = flatten ( JSON_MAPPER . readValue ( f , Map . class ) ) ; } else if ( f . getName ( ) . endsWith ( YAML_EXTENSION ) || f . getName ( ) . endsWith ( YML_EXTENSION ) ) { map = flatten ( YAML_MAPPER . readValue ( f , Map . class ) ) ; } else if ( f . getName ( ) . endsWith ( PROPERTIES_EXTENSION ) ) { Properties properties = new Properties ( ) ; properties . load ( new FileInputStream ( f ) ) ; map = propertiesToMap ( properties ) ; } else { throw new IllegalArgumentException ( "Can't read configuration from: [" + f . getName ( ) + "]. Unknown file extension." ) ; } return map ; }


Input: Flattens a nested map into a Map<String String > . [CODESPLIT] private Map < String , String > flatten ( Map map ) { Map < String , String > flat = new HashMap <> ( ) ; for ( Object key : map . keySet ( ) ) { String stringKey = String . valueOf ( key ) ; Object value = map . get ( key ) ; if ( value instanceof String ) { flat . put ( stringKey , ( String ) value ) ; } else if ( value instanceof Map ) { for ( Map . Entry < String , String > entry : flatten ( ( Map ) value ) . entrySet ( ) ) { flat . put ( new StringBuilder ( stringKey ) . append ( DOT ) . append ( entry . getKey ( ) ) . toString ( ) , entry . getValue ( ) ) ; } } else { flat . put ( stringKey , String . valueOf ( value ) ) ; } } return flat ; }


Input: Converts a { [CODESPLIT] private Map < String , String > propertiesToMap ( Properties properties ) { Map < String , String > map = new HashMap <> ( ) ; for ( Map . Entry < Object , Object > entry : properties . entrySet ( ) ) { map . put ( String . valueOf ( entry . getKey ( ) ) , String . valueOf ( entry . getValue ( ) ) ) ; } return map ; }


Input: Adds a port to the list . [CODESPLIT] private void addPortIfValid ( Map < String , Integer > map , String key , String port ) { if ( StringUtils . isNotBlank ( port ) ) { String t = port . trim ( ) ; if ( t . matches ( NUMBER_REGEX ) ) { map . put ( key , Integer . parseInt ( t ) ) ; } } }


Input: ======================================================================================== [CODESPLIT] private HTTPGetAction getHTTPGetAction ( String getUrl ) { if ( getUrl == null || ! getUrl . subSequence ( 0 , 4 ) . toString ( ) . equalsIgnoreCase ( "http" ) ) { return null ; } try { URL url = new URL ( getUrl ) ; return new HTTPGetAction ( url . getHost ( ) , null /* headers */ , url . getPath ( ) , new IntOrString ( url . getPort ( ) ) , url . getProtocol ( ) . toUpperCase ( ) ) ; } catch ( MalformedURLException e ) { throw new IllegalArgumentException ( "Invalid URL " + getUrl + " given for HTTP GET readiness check" ) ; } }


Input: Method used in MOJO [CODESPLIT] public String getDockerJsonConfigString ( final Settings settings , final String serverId ) { Server server = getServer ( settings , serverId ) ; if ( server == null ) { return "" ; } JsonObject auth = new JsonObject ( ) ; auth . add ( "username" , new JsonPrimitive ( server . getUsername ( ) ) ) ; auth . add ( "password" , new JsonPrimitive ( server . getPassword ( ) ) ) ; String mail = getConfigurationValue ( server , "email" ) ; if ( ! StringUtils . isBlank ( mail ) ) { auth . add ( "email" , new JsonPrimitive ( mail ) ) ; } JsonObject json = new JsonObject ( ) ; json . add ( serverId , auth ) ; return json . toString ( ) ; }


Input: Gets plugin configuration values . Since there can be inner values it returns a Map of Objects where an Object can be a simple type List or another Map . [CODESPLIT] public Optional < Map < String , Object > > getPluginConfiguration ( String system , String id ) { return pluginConfigLookup . apply ( system , id ) ; }


Input: Gets configuration values . Since there can be inner values it returns a Map of Objects where an Object can be a simple type List or another Map . [CODESPLIT] public Optional < Map < String , Object > > getSecretConfiguration ( String id ) { return secretConfigLookup . apply ( id ) ; }


Input: Download with showing the progress a given URL and store it in a file [CODESPLIT] public static void download ( Logger log , URL downloadUrl , File target ) throws MojoExecutionException { log . progressStart ( ) ; try { OkHttpClient client = new OkHttpClient . Builder ( ) . readTimeout ( 30 , TimeUnit . MINUTES ) . build ( ) ; Request request = new Request . Builder ( ) . url ( downloadUrl ) . build ( ) ; Response response = client . newCall ( request ) . execute ( ) ; try ( OutputStream out = new FileOutputStream ( target ) ; InputStream im = response . body ( ) . byteStream ( ) ) { long length = response . body ( ) . contentLength ( ) ; InputStream in = response . body ( ) . byteStream ( ) ; byte [ ] buffer = new byte [ 8192 ] ; long readBytes = 0 ; while ( true ) { int len = in . read ( buffer ) ; readBytes += len ; log . progressUpdate ( target . getName ( ) , "Downloading" , getProgressBar ( readBytes , length ) ) ; if ( len <= 0 ) { out . flush ( ) ; break ; } out . write ( buffer , 0 , len ) ; } } } catch ( IOException e ) { throw new MojoExecutionException ( "Failed to download URL " + downloadUrl + " to  " + target + ": " + e , e ) ; } finally { log . progressFinished ( ) ; } }


Input: Find a free ( on localhost ) random port in the specified range after the given number of attempts . [CODESPLIT] public static int getFreeRandomPort ( int min , int max , int attempts ) { Random random = new Random ( ) ; for ( int i = 0 ; i < attempts ; i ++ ) { int port = min + random . nextInt ( max - min + 1 ) ; try ( Socket socket = new Socket ( "localhost" , port ) ) { } catch ( ConnectException e ) { return port ; } catch ( IOException e ) { throw new IllegalStateException ( "Error while trying to check open ports" , e ) ; } } throw new IllegalStateException ( "Cannot find a free random port in the range [" + min + ", " + max + "] after " + attempts + " attempts" ) ; }


Input:
Compares two version strings such that 1 . 10 . 1 > 1 . 4 etc [CODESPLIT] public static int compareVersions ( String v1 , String v2 ) { String [ ] components1 = split ( v1 ) ; String [ ] components2 = split ( v2 ) ; int diff ; int length = Math . min ( components1 . length , components2 . length ) ; for ( int i = 0 ; i < length ; i ++ ) { String s1 = components1 [ i ] ; String s2 = components2 [ i ] ; Integer i1 = tryParseInteger ( s1 ) ; Integer i2 = tryParseInteger ( s2 ) ; if ( i1 != null && i2 != null ) { diff = i1 . compareTo ( i2 ) ; } else { // lets assume strings instead diff = s1 . compareTo ( s2 ) ; } if ( diff != 0 ) { return diff ; } } diff = Integer . compare ( components1 . length , components2 . length ) ; if ( diff == 0 ) { if ( v1 == v2 ) { return 0 ; } /* if v1 == null then v2 can't be null here (see 'if' above).
               So for v1 == null its always smaller than v2 */ ; return v1 != null ? v1 . compareTo ( v2 ) : - 1 ; } return diff ; }


Input: Find a profile . Profiles are looked up at various locations : [CODESPLIT] public static Profile findProfile ( String profileArg , File resourceDir ) throws IOException { try { String profile = profileArg == null ? DEFAULT_PROFILE : profileArg ; Profile profileFound = lookup ( profile , resourceDir ) ; if ( profileFound != null ) { if ( profileFound . getParentProfile ( ) != null ) { profileFound = inheritFromParentProfile ( profileFound , resourceDir ) ; log . info ( profileFound + " inheriting resources from " + profileFound . getParentProfile ( ) ) ; } return profileFound ; } else { throw new IllegalArgumentException ( "No profile '" + profile + "' defined" ) ; } } catch ( IOException e ) { throw new IOException ( "Error while looking up profile " + profileArg + ": " + e . getMessage ( ) , e ) ; } }


Input: Find an enricher or generator config possibly via a profile and merge it with a given configuration . [CODESPLIT] public static ProcessorConfig blendProfileWithConfiguration ( ProcessorConfigurationExtractor configExtractor , String profile , File resourceDir , ProcessorConfig config ) throws IOException { // Get specified profile or the default profile ProcessorConfig profileConfig = extractProcesssorConfiguration ( configExtractor , profile , resourceDir ) ; return ProcessorConfig . mergeProcessorConfigs ( config , profileConfig ) ; }


Input: Lookup profiles from a given directory and merge it with a profile of the same name found in the classpath [CODESPLIT] public static Profile lookup ( String name , File directory ) throws IOException { // First check from the classpath, these profiles are used as a basis List < Profile > profiles = readProfileFromClasspath ( name ) ; File profileFile = findProfileYaml ( directory ) ; if ( profileFile != null ) { List < Profile > fileProfiles = fromYaml ( new FileInputStream ( profileFile ) ) ; for ( Profile profile : fileProfiles ) { if ( profile . getName ( ) . equals ( name ) ) { profiles . add ( profile ) ; break ; } } } // "larger" orders are "earlier" in the list Collections . sort ( profiles , Collections . < Profile > reverseOrder ( ) ) ; return mergeProfiles ( profiles ) ; }


Input: Read all default profiles first then merge in custom profiles found on the classpath [CODESPLIT] private static List < Profile > readProfileFromClasspath ( String name ) throws IOException { List < Profile > ret = new ArrayList <> ( ) ; ret . addAll ( readAllFromClasspath ( name , "default" ) ) ; ret . addAll ( readAllFromClasspath ( name , "" ) ) ; return ret ; }


Input: Read all profiles found in the classpath . [CODESPLIT] public static List < Profile > readAllFromClasspath ( String name , String ext ) throws IOException { List < Profile > ret = new ArrayList <> ( ) ; for ( String location : getMetaInfProfilePaths ( ext ) ) { for ( String url : ClassUtil . getResources ( location ) ) { for ( Profile profile : fromYaml ( new URL ( url ) . openStream ( ) ) ) { if ( name . equals ( profile . getName ( ) ) ) { ret . add ( profile ) ; } } } } return ret ; }


Input: check for various variations of profile files [CODESPLIT] private static File findProfileYaml ( File directory ) { for ( String profileFile : PROFILE_FILENAMES ) { File ret = new File ( directory , String . format ( profileFile , "" ) ) ; if ( ret . exists ( ) ) { return ret ; } } return null ; }


Input: prepend meta - inf location [CODESPLIT] private static List < String > getMetaInfProfilePaths ( String ext ) { List < String > ret = new ArrayList <> ( PROFILE_FILENAMES . length ) ; for ( String p : PROFILE_FILENAMES ) { ret . add ( "META-INF/fabric8/" + getProfileFileName ( p , ext ) ) ; } return ret ; }


Input: Load a profile from an input stream . This must be in YAML format [CODESPLIT] public static List < Profile > fromYaml ( InputStream is ) throws IOException { TypeReference < List < Profile >> typeRef = new TypeReference < List < Profile > > ( ) { } ; return mapper . readValue ( is , typeRef ) ; }


Input: Find all classes below a certain directory which contain main () classes [CODESPLIT] public static List < String > findMainClasses ( File rootDir ) throws IOException { List < String > ret = new ArrayList <> ( ) ; if ( ! rootDir . exists ( ) ) { return ret ; } if ( ! rootDir . isDirectory ( ) ) { throw new IllegalArgumentException ( String . format ( "Path %s is not a directory" , rootDir . getPath ( ) ) ) ; } findClasses ( ret , rootDir , rootDir . getAbsolutePath ( ) + "/" ) ; return ret ; }


Input: ================================= [CODESPLIT] private void addGitServiceUrl ( Map < String , String > annotations , String repoName , String gitCommitId ) { String username = getGitUserName ( ) ; // this requires online access to kubernetes so we should silently fail if no connection String gogsUrl = getExternalServiceURL ( getConfig ( Config . gitService ) , "http" ) ; String rootGitUrl = String . format ( "%s/%s/%s" , gogsUrl , username , repoName ) ; rootGitUrl = String . format ( "%s/%s/%s" , rootGitUrl , "commit" , gitCommitId ) ; if ( StringUtils . isNotBlank ( rootGitUrl ) ) { annotations . put ( Fabric8Annotations . GIT_URL . value ( ) , rootGitUrl ) ; } }


Input: This method overrides the ImagePullPolicy value by the value provided in XML config . [CODESPLIT] private String getImagePullPolicy ( ResourceConfig resourceConfig , String defaultValue ) { if ( resourceConfig != null ) { return resourceConfig . getImagePullPolicy ( ) != null ? resourceConfig . getImagePullPolicy ( ) : defaultValue ; } return defaultValue ; }


Input: Returns true if we are in OpenShift S2I binary building mode [CODESPLIT] protected boolean isOpenShiftMode ( ) { Properties properties = getContext ( ) . getConfiguration ( ) . getProperties ( ) ; if ( properties != null ) { return RuntimeMode . isOpenShiftMode ( properties ) ; } return false ; }


Input: This method just makes sure that the replica count provided in XML config overrides the default option ; and resource fragments are always given topmost priority . [CODESPLIT] protected int getReplicaCount ( KubernetesListBuilder builder , ResourceConfig xmlResourceConfig , int defaultValue ) { if ( xmlResourceConfig != null ) { List < HasMetadata > items = builder . buildItems ( ) ; for ( HasMetadata item : items ) { if ( item instanceof Deployment ) { if ( ( ( Deployment ) item ) . getSpec ( ) . getReplicas ( ) != null ) { return ( ( Deployment ) item ) . getSpec ( ) . getReplicas ( ) ; } } if ( item instanceof DeploymentConfig ) { if ( ( ( DeploymentConfig ) item ) . getSpec ( ) . getReplicas ( ) != null ) { return ( ( DeploymentConfig ) item ) . getSpec ( ) . getReplicas ( ) ; } } } return xmlResourceConfig . getReplicas ( ) > 0 ? xmlResourceConfig . getReplicas ( ) : defaultValue ; } return defaultValue ; }


Input: Returns the first child element for the given name [CODESPLIT] public static Element firstChild ( Element element , String name ) { NodeList nodes = element . getChildNodes ( ) ; if ( nodes != null ) { for ( int i = 0 , size = nodes . getLength ( ) ; i < size ; i ++ ) { Node item = nodes . item ( i ) ; if ( item instanceof Element ) { Element childElement = ( Element ) item ; if ( name . equals ( childElement . getTagName ( ) ) ) { return childElement ; } } } } return null ; }


Input: ================================================================================================ [CODESPLIT] private static String getTextContent ( final Node node ) { switch ( node . getNodeType ( ) ) { case Node . ELEMENT_NODE : case Node . ATTRIBUTE_NODE : case Node . ENTITY_NODE : case Node . ENTITY_REFERENCE_NODE : case Node . DOCUMENT_FRAGMENT_NODE : return mergeTextContent ( node . getChildNodes ( ) ) ; case Node . TEXT_NODE : case Node . CDATA_SECTION_NODE : case Node . COMMENT_NODE : case Node . PROCESSING_INSTRUCTION_NODE : return node . getNodeValue ( ) ; case Node . DOCUMENT_NODE : case Node . DOCUMENT_TYPE_NODE : case Node . NOTATION_NODE : default : return null ; } }


Input: Applies the given DTOs onto the Kubernetes master [CODESPLIT] public void apply ( Object dto , String sourceName ) throws Exception { if ( dto instanceof List ) { List list = ( List ) dto ; for ( Object element : list ) { if ( dto == element ) { log . warn ( "Found recursive nested object for " + dto + " of class: " + dto . getClass ( ) . getName ( ) ) ; continue ; } apply ( element , sourceName ) ; } } else if ( dto instanceof KubernetesList ) { applyList ( ( KubernetesList ) dto , sourceName ) ; } else if ( dto != null ) { applyEntity ( dto , sourceName ) ; } }


Input: Applies the given DTOs onto the Kubernetes master [CODESPLIT] private void applyEntity ( Object dto , String sourceName ) throws Exception { if ( dto instanceof Pod ) { applyPod ( ( Pod ) dto , sourceName ) ; } else if ( dto instanceof ReplicationController ) { applyReplicationController ( ( ReplicationController ) dto , sourceName ) ; } else if ( dto instanceof Service ) { applyService ( ( Service ) dto , sourceName ) ; } else if ( dto instanceof Route ) { applyRoute ( ( Route ) dto , sourceName ) ; } else if ( dto instanceof BuildConfig ) { applyBuildConfig ( ( BuildConfig ) dto , sourceName ) ; } else if ( dto instanceof DeploymentConfig ) { DeploymentConfig resource = ( DeploymentConfig ) dto ; OpenShiftClient openShiftClient = getOpenShiftClient ( ) ; if ( openShiftClient != null ) { applyResource ( resource , sourceName , openShiftClient . deploymentConfigs ( ) ) ; } else { log . warn ( "Not connected to OpenShift cluster so cannot apply entity " + dto ) ; } } else if ( dto instanceof RoleBinding ) { applyRoleBinding ( ( RoleBinding ) dto , sourceName ) ; } else if ( dto instanceof Role ) { Role resource = ( Role ) dto ; OpenShiftClient openShiftClient = getOpenShiftClient ( ) ; if ( openShiftClient != null ) { applyResource ( resource , sourceName , openShiftClient . rbac ( ) . roles ( ) ) ; } else { log . warn ( "Not connected to OpenShift cluster so cannot apply entity " + dto ) ; } } else if ( dto instanceof ImageStream ) { applyImageStream ( ( ImageStream ) dto , sourceName ) ; } else if ( dto instanceof OAuthClient ) { applyOAuthClient ( ( OAuthClient ) dto , sourceName ) ; } else if ( dto instanceof Template ) { applyTemplate ( ( Template ) dto , sourceName ) ; } else if ( dto instanceof ServiceAccount ) { applyServiceAccount ( ( ServiceAccount ) dto , sourceName ) ; } else if ( dto instanceof Secret ) { applySecret ( ( Secret ) dto , sourceName ) ; } else if ( dto instanceof ConfigMap ) { applyResource ( ( ConfigMap ) dto , sourceName , kubernetesClient . configMaps ( ) ) ; } else if ( dto instanceof DaemonSet ) { applyResource ( ( DaemonSet ) dto , sourceName , kubernetesClient . extensions ( ) . daemonSets ( ) ) ; } else if ( dto instanceof Deployment ) { applyResource ( ( Deployment ) dto , sourceName , kubernetesClient . extensions ( ) . deployments ( ) ) ; } else if ( dto instanceof ReplicaSet ) { applyResource ( ( ReplicaSet ) dto , sourceName , kubernetesClient . extensions ( ) . replicaSets ( ) ) ; } else if ( dto instanceof StatefulSet ) { applyResource ( ( StatefulSet ) dto , sourceName , kubernetesClient . apps ( ) . statefulSets ( ) ) ; } else if ( dto instanceof Ingress ) { applyResource ( ( Ingress ) dto , sourceName , kubernetesClient . extensions ( ) . ingresses ( ) ) ; } else if ( dto instanceof PersistentVolumeClaim ) { applyPersistentVolumeClaim ( ( PersistentVolumeClaim ) dto , sourceName ) ; } else if ( dto instanceof HasMetadata ) { HasMetadata entity = ( HasMetadata ) dto ; try { log . info ( "Applying " + getKind ( entity ) + " " + getName ( entity ) + " from " + sourceName ) ; kubernetesClient . resource ( entity ) . inNamespace ( getNamespace ( ) ) . createOrReplace ( ) ; } catch ( Exception e ) { onApplyError ( "Failed to create " + getKind ( entity ) + " from " + sourceName + ". " + e , e ) ; } } else { throw new IllegalArgumentException ( "Unknown entity type " + dto ) ; } }


Input: Creates / updates the template and processes it returning the processed DTOs [CODESPLIT] public Object applyTemplate ( Template entity , String sourceName ) throws Exception { installTemplate ( entity , sourceName ) ; return processTemplate ( entity , sourceName ) ; }


Input: Installs the template into the namespace without processing it [CODESPLIT] public void installTemplate ( Template entity , String sourceName ) { OpenShiftClient openShiftClient = getOpenShiftClient ( ) ; if ( openShiftClient == null ) { // lets not install the template on Kubernetes! return ; } if ( ! isProcessTemplatesLocally ( ) ) { String namespace = getNamespace ( ) ; String id = getName ( entity ) ; Objects . requireNonNull ( id , "No name for " + entity + " " + sourceName ) ; Template old = openShiftClient . templates ( ) . inNamespace ( namespace ) . withName ( id ) . get ( ) ; if ( isRunning ( old ) ) { if ( UserConfigurationCompare . configEqual ( entity , old ) ) { log . info ( "Template has not changed so not doing anything" ) ; } else { boolean recreateMode = isRecreateMode ( ) ; // TODO seems you can't update templates right now recreateMode = true ; if ( recreateMode ) { openShiftClient . templates ( ) . inNamespace ( namespace ) . withName ( id ) . delete ( ) ; doCreateTemplate ( entity , namespace , sourceName ) ; } else { log . info ( "Updating a Template from " + sourceName ) ; try { Object answer = openShiftClient . templates ( ) . inNamespace ( namespace ) . withName ( id ) . replace ( entity ) ; log . info ( "Updated Template: " + answer ) ; } catch ( Exception e ) { onApplyError ( "Failed to update Template from " + sourceName + ". " + e + ". " + entity , e ) ; } } } } else { if ( ! isAllowCreate ( ) ) { log . warn ( "Creation disabled so not creating a Template from " + sourceName + " namespace " + namespace + " name " + getName ( entity ) ) ; } else { doCreateTemplate ( entity , namespace , sourceName ) ; } } } }


Input: Creates / updates a service account and processes it returning the processed DTOs [CODESPLIT] public void applyServiceAccount ( ServiceAccount serviceAccount , String sourceName ) throws Exception { String namespace = getNamespace ( ) ; String id = getName ( serviceAccount ) ; Objects . requireNonNull ( id , "No name for " + serviceAccount + " " + sourceName ) ; if ( isServicesOnlyMode ( ) ) { log . debug ( "Only processing Services right now so ignoring ServiceAccount: " + id ) ; return ; } ServiceAccount old = kubernetesClient . serviceAccounts ( ) . inNamespace ( namespace ) . withName ( id ) . get ( ) ; if ( isRunning ( old ) ) { if ( UserConfigurationCompare . configEqual ( serviceAccount , old ) ) { log . info ( "ServiceAccount has not changed so not doing anything" ) ; } else { if ( isRecreateMode ( ) ) { kubernetesClient . serviceAccounts ( ) . inNamespace ( namespace ) . withName ( id ) . delete ( ) ; doCreateServiceAccount ( serviceAccount , namespace , sourceName ) ; } else { log . info ( "Updating a ServiceAccount from " + sourceName ) ; try { Object answer = kubernetesClient . serviceAccounts ( ) . inNamespace ( namespace ) . withName ( id ) . replace ( serviceAccount ) ; logGeneratedEntity ( "Updated ServiceAccount: " , namespace , serviceAccount , answer ) ; } catch ( Exception e ) { onApplyError ( "Failed to update ServiceAccount from " + sourceName + ". " + e + ". " + serviceAccount , e ) ; } } } } else { if ( ! isAllowCreate ( ) ) { log . warn ( "Creation disabled so not creating a ServiceAccount from " + sourceName + " namespace " + namespace + " name " + getName ( serviceAccount ) ) ; } else { doCreateServiceAccount ( serviceAccount , namespace , sourceName ) ; } } }


Input: Removes all the tags with the given name [CODESPLIT] private int removeTagByName ( List < TagReference > tags , String tagName ) { List < TagReference > removeTags = new ArrayList <> ( ) ; for ( TagReference tag : tags ) { if ( Objects . equals ( tagName , tag . getName ( ) ) ) { removeTags . add ( tag ) ; } } tags . removeAll ( removeTags ) ; return removeTags . size ( ) ; }


Input: Returns true if the namespace is created [CODESPLIT] public boolean applyNamespace ( Namespace entity ) { String namespace = getOrCreateMetadata ( entity ) . getName ( ) ; log . info ( "Using namespace: " + namespace ) ; String name = getName ( entity ) ; Objects . requireNonNull ( name , "No name for " + entity ) ; Namespace old = kubernetesClient . namespaces ( ) . withName ( name ) . get ( ) ; if ( ! isRunning ( old ) ) { try { Object answer = kubernetesClient . namespaces ( ) . create ( entity ) ; logGeneratedEntity ( "Created namespace: " , namespace , entity , answer ) ; return true ; } catch ( Exception e ) { onApplyError ( "Failed to create namespace: " + name + " due " + e . getMessage ( ) , e ) ; } } return false ; }


Input: Creates and return a project in openshift [CODESPLIT] public boolean applyProject ( Project project ) { return applyProjectRequest ( new ProjectRequestBuilder ( ) . withDisplayName ( project . getMetadata ( ) . getName ( ) ) . withMetadata ( project . getMetadata ( ) ) . build ( ) ) ; }


Input: Returns true if the ProjectRequest is created [CODESPLIT] public boolean applyProjectRequest ( ProjectRequest entity ) { String namespace = getOrCreateMetadata ( entity ) . getName ( ) ; log . info ( "Using project: " + namespace ) ; String name = getName ( entity ) ; Objects . requireNonNull ( name , "No name for " + entity ) ; OpenShiftClient openshiftClient = getOpenShiftClient ( ) ; if ( openshiftClient == null ) { log . warn ( "Cannot check for Project " + namespace + " as not running against OpenShift!" ) ; return false ; } boolean exists = checkNamespace ( name ) ; // We may want to be more fine-grained on the phase of the project if ( ! exists ) { try { Object answer = openshiftClient . projectrequests ( ) . create ( entity ) ; logGeneratedEntity ( "Created ProjectRequest: " , namespace , entity , answer ) ; return true ; } catch ( Exception e ) { onApplyError ( "Failed to create ProjectRequest: " + name + " due " + e . getMessage ( ) , e ) ; } } return false ; }


Input: Returns the namespace defined in the entity or the configured namespace [CODESPLIT] protected String getNamespace ( HasMetadata entity ) { String answer = KubernetesHelper . getNamespace ( entity ) ; if ( StringUtils . isBlank ( answer ) ) { answer = getNamespace ( ) ; } // lest make sure the namespace exists applyNamespace ( answer ) ; return answer ; }


Input: Logs an error applying some JSON to Kubernetes and optionally throws an exception [CODESPLIT] protected void onApplyError ( String message , Exception e ) { log . error ( message , e ) ; throw new RuntimeException ( message , e ) ; }


Input: ==================================================================================== [CODESPLIT] @ GET @ Produces ( "text/plain" ) public String peng ( @ PathParam ( "id" ) String id ) { Stroke stroke = Stroke . play ( strength ) ; return pengId + " " + stroke . toString ( ) ; }


Input: ============================================================================= [CODESPLIT] private void ensureSpringDevToolSecretToken ( ) throws MojoExecutionException { Properties properties = SpringBootUtil . getSpringBootApplicationProperties ( MavenUtil . getCompileClassLoader ( getProject ( ) ) ) ; String remoteSecret = properties . getProperty ( DEV_TOOLS_REMOTE_SECRET ) ; if ( Strings . isNullOrEmpty ( remoteSecret ) ) { addSecretTokenToApplicationProperties ( ) ; throw new MojoExecutionException ( "No spring.devtools.remote.secret found in application.properties. Plugin has added it, please re-run goals" ) ; } }


Input: This method will create a default Namespace or Project if a namespace property is specified in the xml resourceConfig or as a parameter to a mojo . [CODESPLIT] @ Override public void create ( PlatformMode platformMode , KubernetesListBuilder builder ) { final String name = config . getNamespace ( ) ; if ( name == null || name . isEmpty ( ) ) { return ; } if ( ! KubernetesResourceUtil . checkForKind ( builder , NAMESPACE_KINDS ) ) { String type = getConfig ( Config . type ) ; if ( "project" . equalsIgnoreCase ( type ) || "namespace" . equalsIgnoreCase ( type ) ) { if ( platformMode == PlatformMode . kubernetes ) { log . info ( "Adding a default Namespace:" + config . getNamespace ( ) ) ; Namespace namespace = handlerHub . getNamespaceHandler ( ) . getNamespace ( config . getNamespace ( ) ) ; builder . addToNamespaceItems ( namespace ) ; } else { log . info ( "Adding a default Project" + config . getNamespace ( ) ) ; Project project = handlerHub . getProjectHandler ( ) . getProject ( config . getNamespace ( ) ) ; builder . addToProjectItems ( project ) ; } } } }


Input: This method will annotate all the items in the KubernetesListBuilder with the created new namespace or project . [CODESPLIT] @ Override public void enrich ( PlatformMode platformMode , KubernetesListBuilder builder ) { builder . accept ( new TypedVisitor < ObjectMetaBuilder > ( ) { private String getNamespaceName ( ) { String name = null ; if ( config . getNamespace ( ) != null && ! config . getNamespace ( ) . isEmpty ( ) ) { name = config . getNamespace ( ) ; } name = builder . getItems ( ) . stream ( ) . filter ( item -> Arrays . asList ( NAMESPACE_KINDS ) . contains ( item . getKind ( ) ) ) . findFirst ( ) . get ( ) . getMetadata ( ) . getName ( ) ; return name ; } @ Override public void visit ( ObjectMetaBuilder metaBuilder ) { if ( ! KubernetesResourceUtil . checkForKind ( builder , NAMESPACE_KINDS ) ) { return ; } String name = getNamespaceName ( ) ; if ( name == null || name . isEmpty ( ) ) { return ; } metaBuilder . withNamespace ( name ) . build ( ) ; } } ) ; // Removing namespace annotation from the namespace and project objects being generated. // to avoid unncessary trouble while applying these resources. builder . accept ( new TypedVisitor < NamespaceBuilder > ( ) { @ Override public void visit ( NamespaceBuilder builder ) { builder . withNewStatus ( "active" ) . editMetadata ( ) . withNamespace ( null ) . endMetadata ( ) . build ( ) ; } } ) ; builder . accept ( new TypedVisitor < ProjectBuilder > ( ) { @ Override public void visit ( ProjectBuilder builder ) { builder . withNewStatus ( "active" ) . editMetadata ( ) . withNamespace ( null ) . endMetadata ( ) . build ( ) ; } } ) ; }


Input: Transforms the Dom object into a Map . This Map can contain pairs key / value where value can be a simple type another Map ( Inner objects ) and a list of simple types . [CODESPLIT] public static Map < String , Object > extract ( Xpp3Dom root ) { if ( root == null ) { return new HashMap <> ( ) ; } return getElement ( root ) ; }


Input: Hook for adding extra environment vars [CODESPLIT] protected Map < String , String > getEnv ( boolean prePackagePhase ) throws MojoExecutionException { Map < String , String > ret = new HashMap <> ( ) ; if ( ! isFatJar ( ) ) { String mainClass = getConfig ( Config . mainClass ) ; if ( mainClass == null ) { mainClass = mainClassDetector . getMainClass ( ) ; if ( mainClass == null ) { if ( ! prePackagePhase ) { throw new MojoExecutionException ( "Cannot extract main class to startup" ) ; } } } if ( mainClass != null ) { log . verbose ( "Detected main class %s" , mainClass ) ; ret . put ( JAVA_MAIN_CLASS_ENV_VAR , mainClass ) ; } } List < String > javaOptions = getExtraJavaOptions ( ) ; if ( javaOptions . size ( ) > 0 ) { ret . put ( JAVA_OPTIONS , StringUtils . join ( javaOptions . iterator ( ) , " " ) ) ; } return ret ; }


Input: Parses a duration string anr returns its value in seconds . [CODESPLIT] public static Integer durationSeconds ( String duration ) { BigDecimal ns = durationNs ( duration ) ; if ( ns == null ) { return null ; } BigDecimal sec = ns . divide ( new BigDecimal ( 1_000_000_000 ) ) ; if ( sec . compareTo ( new BigDecimal ( Integer . MAX_VALUE ) ) > 0 ) { throw new IllegalArgumentException ( "Integer Overflow" ) ; } return sec . intValue ( ) ; }


Input: Parses a duration string anr returns its value in nanoseconds . [CODESPLIT] public static BigDecimal durationNs ( String durationP ) { if ( durationP == null ) { return null ; } String duration = durationP . trim ( ) ; if ( duration . length ( ) == 0 ) { return null ; } int unitPos = 1 ; while ( unitPos < duration . length ( ) && ( Character . isDigit ( duration . charAt ( unitPos ) ) || duration . charAt ( unitPos ) == ' ' ) ) { unitPos ++ ; } if ( unitPos >= duration . length ( ) ) { throw new IllegalArgumentException ( "Time unit not found in string: " + duration ) ; } String tail = duration . substring ( unitPos ) ; Long multiplier = null ; Integer unitEnd = null ; for ( int i = 0 ; i < TIME_UNITS . length ; i ++ ) { if ( tail . startsWith ( TIME_UNITS [ i ] ) ) { multiplier = UNIT_MULTIPLIERS [ i ] ; unitEnd = unitPos + TIME_UNITS [ i ] . length ( ) ; break ; } } if ( multiplier == null ) { throw new IllegalArgumentException ( "Unknown time unit in string: " + duration ) ; } BigDecimal value = new BigDecimal ( duration . substring ( 0 , unitPos ) ) ; value = value . multiply ( BigDecimal . valueOf ( multiplier ) ) ; String remaining = duration . substring ( unitEnd ) ; BigDecimal remainingValue = durationNs ( remaining ) ; if ( remainingValue != null ) { value = value . add ( remainingValue ) ; } return value ; }


Input: Scan the project s output directory for certain files . [CODESPLIT] protected String [ ] scanFiles ( String ... patterns ) { String buildOutputDir = project . getBuild ( ) . getDirectory ( ) ; if ( buildOutputDir != null && new File ( buildOutputDir ) . exists ( ) ) { DirectoryScanner directoryScanner = new DirectoryScanner ( ) ; directoryScanner . setBasedir ( buildOutputDir ) ; directoryScanner . setIncludes ( patterns ) ; directoryScanner . scan ( ) ; return directoryScanner . getIncludedFiles ( ) ; } else { return new String [ 0 ] ; } }


Input: Should we try to create an external URL for the given service? <p / > By default lets ignore the kubernetes services and any service which does not expose ports 80 and 443 [CODESPLIT] private boolean shouldCreateExternalURLForService ( Service service , String id ) { if ( "kubernetes" . equals ( id ) || "kubernetes-ro" . equals ( id ) ) { return false ; } Set < Integer > ports = getPorts ( service ) ; log . debug ( "Service " + id + " has ports: " + ports ) ; if ( ports . size ( ) == 1 ) { String type = null ; ServiceSpec spec = service . getSpec ( ) ; if ( spec != null ) { type = spec . getType ( ) ; if ( Objects . equals ( type , "LoadBalancer" ) ) { return true ; } } log . info ( "Not generating route for service " + id + " type is not LoadBalancer: " + type ) ; return false ; } else { log . info ( "Not generating route for service " + id + " as only single port services are supported. Has ports: " + ports ) ; return false ; } }


Input: Lets disable OpenShift - only features if we are not running on OpenShift [CODESPLIT] protected void disableOpenShiftFeatures ( ApplyService applyService ) { // TODO we could check if the Templates service is running and if so we could still support templates? this . processTemplatesLocally = true ; applyService . setSupportOAuthClients ( false ) ; applyService . setProcessTemplatesLocally ( true ) ; }


Input: Returns true if there is an existing ingress rule for the given service [CODESPLIT] private boolean serviceHasIngressRule ( List < Ingress > ingresses , Service service ) { String serviceName = KubernetesHelper . getName ( service ) ; for ( Ingress ingress : ingresses ) { IngressSpec spec = ingress . getSpec ( ) ; if ( spec == null ) { break ; } List < IngressRule > rules = spec . getRules ( ) ; if ( rules == null ) { break ; } for ( IngressRule rule : rules ) { HTTPIngressRuleValue http = rule . getHttp ( ) ; if ( http == null ) { break ; } List < HTTPIngressPath > paths = http . getPaths ( ) ; if ( paths == null ) { break ; } for ( HTTPIngressPath path : paths ) { IngressBackend backend = path . getBackend ( ) ; if ( backend == null ) { break ; } if ( Objects . equals ( serviceName , backend . getServiceName ( ) ) ) { return true ; } } } } return false ; }


Input: Returns the root project folder [CODESPLIT] protected File getRootProjectFolder ( ) { File answer = null ; MavenProject project = getProject ( ) ; while ( project != null ) { File basedir = project . getBasedir ( ) ; if ( basedir != null ) { answer = basedir ; } project = project . getParent ( ) ; } return answer ; }


Input: Returns the root project folder [CODESPLIT] protected MavenProject getRootProject ( ) { MavenProject project = getProject ( ) ; while ( project != null ) { MavenProject parent = project . getParent ( ) ; if ( parent == null ) { break ; } project = parent ; } return project ; }


Input: Customization hook called by the base plugin . [CODESPLIT] @ Override public List < ImageConfiguration > customizeConfig ( List < ImageConfiguration > configs ) { try { ProcessorConfig generatorConfig = ProfileUtil . blendProfileWithConfiguration ( ProfileUtil . GENERATOR_CONFIG , profile , ResourceDirCreator . getFinalResourceDir ( resourceDir , environment ) , generator ) ; GeneratorContext ctx = new GeneratorContext . Builder ( ) . config ( generatorConfig ) . project ( project ) . logger ( log ) . runtimeMode ( mode ) . strategy ( buildStrategy ) . useProjectClasspath ( false ) . build ( ) ; return GeneratorManager . generate ( configs , ctx , true ) ; } catch ( Exception e ) { throw new IllegalArgumentException ( "Cannot extract generator config: " + e , e ) ; } }


Input: This method reads properties file to load custom mapping between kinds and filenames . [CODESPLIT] public Map < String , List < String > > parse ( final InputStream mapping ) { final Properties mappingProperties = new Properties ( ) ; try { mappingProperties . load ( mapping ) ; final Map < String , List < String > > serializedContent = new HashMap <> ( ) ; final Set < String > kinds = mappingProperties . stringPropertyNames ( ) ; for ( String kind : kinds ) { final String filenames = mappingProperties . getProperty ( kind ) ; final String [ ] filenameTypes = filenames . split ( "," ) ; final List < String > scannedFiletypes = new ArrayList <> ( ) ; for ( final String filenameType : filenameTypes ) { scannedFiletypes . add ( filenameType . trim ( ) ) ; } serializedContent . put ( kind , scannedFiletypes ) ; } return serializedContent ; } catch ( IOException e ) { throw new IllegalStateException ( e ) ; } }


Input: Customization hook called by the base plugin . [CODESPLIT] @ Override public List < ImageConfiguration > customizeConfig ( List < ImageConfiguration > configs ) { runtimeMode = clusterAccess . resolveRuntimeMode ( mode , log ) ; log . info ( "Running in [[B]]%s[[B]] mode" , runtimeMode . getLabel ( ) ) ; if ( runtimeMode == RuntimeMode . openshift ) { log . info ( "Using [[B]]OpenShift[[B]] build with strategy [[B]]%s[[B]]" , buildStrategy . getLabel ( ) ) ; } else { log . info ( "Building Docker image in [[B]]Kubernetes[[B]] mode" ) ; } if ( runtimeMode . equals ( PlatformMode . openshift ) ) { Properties properties = project . getProperties ( ) ; if ( ! properties . contains ( RuntimeMode . FABRIC8_EFFECTIVE_PLATFORM_MODE ) ) { properties . setProperty ( RuntimeMode . FABRIC8_EFFECTIVE_PLATFORM_MODE , runtimeMode . toString ( ) ) ; } } try { return GeneratorManager . generate ( configs , getGeneratorContext ( ) , false ) ; } catch ( MojoExecutionException e ) { throw new IllegalArgumentException ( "Cannot extract generator config: " + e , e ) ; } }


Input: Get generator context [CODESPLIT] private GeneratorContext getGeneratorContext ( ) { return new GeneratorContext . Builder ( ) . config ( extractGeneratorConfig ( ) ) . project ( project ) . logger ( log ) . runtimeMode ( runtimeMode ) . strategy ( buildStrategy ) . useProjectClasspath ( useProjectClasspath ) . artifactResolver ( getFabric8ServiceHub ( ) . getArtifactResolverService ( ) ) . build ( ) ; }


Input: Get generator config [CODESPLIT] private ProcessorConfig extractGeneratorConfig ( ) { try { return ProfileUtil . blendProfileWithConfiguration ( ProfileUtil . GENERATOR_CONFIG , profile , ResourceDirCreator . getFinalResourceDir ( resourceDir , environment ) , generator ) ; } catch ( IOException e ) { throw new IllegalArgumentException ( "Cannot extract generator config: " + e , e ) ; } }


Input: Get enricher context [CODESPLIT] public EnricherContext getEnricherContext ( ) { return new MavenEnricherContext . Builder ( ) . project ( project ) . properties ( project . getProperties ( ) ) . session ( session ) . config ( extractEnricherConfig ( ) ) . images ( getResolvedImages ( ) ) . resources ( resources ) . log ( log ) . build ( ) ; }


Input: Get enricher config [CODESPLIT] private ProcessorConfig extractEnricherConfig ( ) { try { return ProfileUtil . blendProfileWithConfiguration ( ProfileUtil . ENRICHER_CONFIG , profile , ResourceDirCreator . getFinalResourceDir ( resourceDir , environment ) , enricher ) ; } catch ( IOException e ) { throw new IllegalArgumentException ( "Cannot extract enricher config: " + e , e ) ; } }


Input: ==================================================================================================== [CODESPLIT] private String extractIconRef ( ) { String iconRef = getConfig ( Config . ref ) ; if ( StringUtils . isBlank ( iconRef ) ) { iconRef = getDefaultIconRef ( ) ; } return iconRef ; }


Input: Lets use the project and its classpath to try figure out what default icon to use [CODESPLIT] private String getDefaultIconRef ( ) { ProjectClassLoaders cls = getContext ( ) . getProjectClassLoaders ( ) ; if ( cls . isClassInCompileClasspath ( false , "io.fabric8.funktion.runtime.Main" ) || getContext ( ) . hasDependency ( "io.fabric8.funktion" , null ) ) { return "funktion" ; } if ( cls . isClassInCompileClasspath ( false , "org.apache.camel.CamelContext" ) ) { return "camel" ; } if ( getContext ( ) . hasPlugin ( null , SpringBootConfigurationHelper . SPRING_BOOT_MAVEN_PLUGIN_ARTIFACT_ID ) || cls . isClassInCompileClasspath ( false , "org.springframework.boot.SpringApplication" ) ) { return "spring-boot" ; } if ( cls . isClassInCompileClasspath ( false , "org.springframework.core.Constants" ) ) { return "spring" ; } if ( cls . isClassInCompileClasspath ( false , "org.vertx.java.core.Handler" , "io.vertx.core.Handler" ) ) { return "vertx" ; } if ( getContext ( ) . hasPlugin ( "org.wildfly.swarm" , "wildfly-swarm-plugin" ) || getContext ( ) . hasDependency ( "org.wildfly.swarm" , null ) ) { return "wildfly-swarm" ; } if ( getContext ( ) . hasPlugin ( "io.thorntail" , "thorntail-maven-plugin" ) || getContext ( ) . hasDependency ( "io.thorntail" , null ) ) { // use the WildFly Swarm icon until there's a dedicated Thorntail icon // Thorntail is a new name of WildFly Swarm return "wildfly-swarm" ; } return null ; }


Input: Copies any local configuration files into the app directory [CODESPLIT] private void copyAppConfigFiles ( File appBuildDir , File appConfigDir ) throws IOException { File [ ] files = appConfigDir . listFiles ( ) ; if ( files != null ) { appBuildDir . mkdirs ( ) ; for ( File file : files ) { File outFile = new File ( appBuildDir , file . getName ( ) ) ; if ( file . isDirectory ( ) ) { copyAppConfigFiles ( outFile , file ) ; } else { Files . copy ( file , outFile ) ; } } } }