e21562f78068c9622e3ed782efd0e3c217c1a4e2
[policy/drools-pdp.git] / policy-management / src / main / server-gen / bin / features
1 #! /bin/bash
2
3 ###
4 # ============LICENSE_START=======================================================
5 # ONAP POLICY
6 # ================================================================================
7 # Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
8 # ================================================================================
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
12
13 #      http://www.apache.org/licenses/LICENSE-2.0
14
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 # ============LICENSE_END=========================================================
21 ##
22
23 # #############################################################
24 # Features Directory Layout:
25 #
26 # POLICY_HOME/
27 #   └── features/
28 #        └── <feature-name>*/
29 #            └── [config]/
30 #            │   └── <config-file>*
31 #            └── lib/
32 #            │   └── [dependencies]/
33 #            │   │   └── <dependent-jar>*
34 #            │   └── feature/
35 #            │       └── <feature-jar>
36 #            └── [install]
37 #                └── [enable]
38 #                └── [disable]
39 #                └── [other-future-operations]
40 #                └── [other-files]
41 #
42 #   <feature-name> directory should not have the "feature-" prefix.
43 #   <config-file> preferable with "feature-" prefix.
44 #
45 # Example:
46 #
47 # POLICY_HOME/
48 #   └── features/
49 #        ├── eelf/
50 #        │   ├── config/
51 #        │   │   ├── logback-eelf.xml
52 #        │   └── lib/
53 #        │   │   └── dependencies/
54 #        │   │   │   └── ONAP-Logging-1.1.0-SNAPSHOT.jar
55 #        │   │   │   └── eelf-core-1.0.0.jar
56 #        │   │   └── feature/
57 #        │   │       └── feature-eelf-1.1.0-SNAPSHOT.jar
58 #        │   └── install/
59 #        │       └── enable
60 #        │       └── disable
61 #        └── healthcheck/
62 #            ├── config/
63 #            │   └── feature-healthcheck.properties
64 #            └── lib/
65 #                └── feature/
66 #                    └── feature-healthcheck-1.1.0-SNAPSHOT.jar
67 # #############################################################
68
69 if [[ ${DEBUG} == y ]]; then
70         echo "-- MAIN --"
71         set -x
72 fi
73         
74 # The directories at play
75
76 LIB=${POLICY_HOME}/lib
77 CONFIG=${POLICY_HOME}/config
78 FEATURES=${POLICY_HOME}/features
79
80 if [[ ! ( -d "${LIB}" && -x "${LIB}" ) ]]; then
81         echo "ERROR: no ${LIB} directory"
82         exit 1
83 fi
84
85 if [[ ! ( -d "${CONFIG}" && -x "${CONFIG}" ) ]]; then
86         echo "ERROR: no ${CONFIG} directory"
87         exit 2
88 fi
89
90 if [[ ! ( -d "${FEATURES}" && -x "${FEATURES}" ) ]]; then
91         echo "ERROR: no ${FEATURES} directory"
92         exit 3
93 fi
94
95 # relative per Feature Directory Paths
96
97 FEATURE_DEPS="lib/dependencies"
98 FEATURE_LIB="lib/feature"
99 FEATURE_CONFIG="config"
100 FEATURE_INSTALL="install"
101
102 featureJars=$(find "${FEATURES}" -name "feature-*.jar" -type f -exec basename {} \; 2> /dev/null)
103 if [[ -z ${featureJars} ]]; then
104         echo "no features"
105         usage
106         exit 0
107 fi
108
109 # default field lengths
110 nameLength=20
111 versionLength=15
112
113 # update field lengths, if needed
114 for jar in ${featureJars} ; do
115         # get file name without 'jar' suffix
116         tmp="${jar%\.jar}"
117
118         # remove feature prefix
119         tmp="${tmp#feature-}"
120                 
121         # get feature name by removing the version portion
122         name="${tmp%%-[0-9]*}"
123
124         # extract version portion of name
125         version="${tmp#${name}-}"
126
127         # grow the size of the name/version field, if needed
128         if (( "${#name}" > nameLength )) ; then
129                 nameLength="${#name}"
130         fi
131         if (( "${#version}" > versionLength )) ; then
132                 versionLength="${#version}"
133         fi
134 done
135
136 # ##########################################################
137 # usage: usage information
138 # ##########################################################
139 function usage
140 {
141                 # print out usage information
142                 cat >&2 <<-'EOF'
143                 Usage:  features status
144                             Get enabled/disabled status on all features
145                         features enable <feature> ...
146                             Enable the specified feature
147                         features disable <feature> ...
148                             Disable the specified feature
149                 EOF
150 }
151
152 # ##########################################################
153 # status: dump out status information
154 # ##########################################################
155 function status
156 {
157         if [[ ${DEBUG} == y ]]; then
158                 echo "-- ${FUNCNAME[0]} $@ --"
159                 set -x
160         fi
161         
162         local tmp name version status
163         local format="%-${nameLength}s %-${versionLength}s %s\n"
164         
165         printf "${format}" "name" "version" "status"
166         printf "${format}" "----" "-------" "------"
167         
168         for jar in ${featureJars} ; do
169                 # get file name without 'jar' suffix
170                 tmp="${jar%\.jar}"
171                 
172                 # remove feature prefix
173                 tmp="${tmp#feature-}"
174
175                 # get feature name by removing the version portion
176                 name="${tmp%%-[0-9]*}"
177
178                 # extract version portion of name
179                 version="${tmp#${name}-}"
180
181                 # determine status
182                 status=disabled
183                 if [[ -e "${LIB}/${jar}" ]] ; then
184                         status=enabled
185                 fi
186                 printf "${format}" "${name}" "${version}" "${status}"
187         done
188 }
189
190 # ##########################################################
191 # depEnableAnalysis(featureName):  
192 #                   reports on potential dependency conflicts
193 #   featureName: name of the feature
194 # ##########################################################
195 function depEnableAnalysis()
196 {
197         if [[ ${DEBUG} == y ]]; then
198                 echo "-- ${FUNCNAME[0]} $@ --"
199                 set -x
200         fi
201         
202         local featureName="$1"
203         local featureDepJars featureDepJarPath depJarName multiVersionJars
204         
205         if [[ -z ${featureName} ]]; then
206                 echo "WARN: no feature name"
207                 return 1
208         fi
209         
210         featureDepJars=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
211         for featureDepJarPath in ${featureDepJars}; do
212                 depJarName=$(basename "${featureDepJarPath}")
213                 
214                 # it could be a base jar
215
216                 if [[ -f "${LIB}"/"${depJarName}" ]]; then
217                         echo "WARN: dependency ${depJarName} already in use"
218                         continue
219                 fi
220                 
221                 # it could be a link from another feature
222
223                 if [[ -L "${LIB}"/"${depJarName}" ]]; then
224                         continue
225                 fi
226                 
227                 # unadvisable if multiple versions exist
228
229                 multiVersionJars=$(ls "${LIB}"/"${depJarName%%-[0-9]*.jar}"-*.jar 2> /dev/null)
230                 if [[ -n "${multiVersionJars}" ]]; then
231                         echo "WARN: other version of library ${depJarName} present: ${multiVersionJars}"
232                         return 2
233                 fi
234         done
235 }
236
237 # ##########################################################
238 # configEnableAnalysis(featureName):  
239 #                   reports on potential dependency conflicts
240 #   featureName: name of the feature
241 # ##########################################################
242 function configEnableAnalysis()
243 {
244         if [[ ${DEBUG} == y ]]; then
245                 echo "-- ${FUNCNAME[0]} $@ --"
246                 set -x
247         fi
248         
249         local featureName="$1"
250         local featureConfigs configPath configFileName
251         
252         if [[ -z ${featureName} ]]; then
253                 echo "WARN: no feature name"
254                 return 1
255         fi
256         
257         featureConfigs=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ 2> /dev/null)
258         for configPath in ${featureConfigs}; do
259                 configFileName=$(basename "${configPath}")
260                 if [[ -e "${LIB}"/"${configFileName}" ]]; then
261                         echo "ERROR: a config file of the same name is already in the base: ${configFileName}"
262                         return 2
263                 fi
264         done
265 }
266
267 # ##########################################################
268 # enableFeatureDeps(featureName):  
269 #                               enables feature dependencies
270 #   featureName: name of the feature
271 # ##########################################################
272 function enableFeatureDeps()
273 {
274         if [[ ${DEBUG} == y ]]; then
275                 echo "-- ${FUNCNAME[0]} $@ --"
276                 set -x
277         fi
278         
279         local featureName="$1"
280         local featureDeps featureDepPath depJarName
281         
282         if [[ -z ${featureName} ]]; then
283                 echo "WARN: no feature name"
284                 return 1
285         fi
286         
287         featureDeps=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
288         for featureDepPath in ${featureDeps}; do
289                 depJarName=$(basename "${featureDepPath}")
290                 if [[ ! -f "${LIB}"/"${depJarName}" ]]; then
291                         ln -s -f "${featureDepPath}" "${LIB}/"
292                 fi
293         done
294 }
295
296 # ##########################################################
297 # enableFeatureConfig(featureName):  
298 #                               enables feature configuration
299 #   featureName: name of the feature
300 # ##########################################################
301 function enableFeatureConfig()
302 {
303         if [[ ${DEBUG} == y ]]; then
304                 echo "-- ${FUNCNAME[0]} $@ --"
305                 set -x
306         fi
307         
308         local featureName="$1"
309         local featureConfigs featureConfigPath
310         
311         if [[ -z ${featureName} ]]; then
312                 echo "WARN: no feature name"
313                 return 1
314         fi
315         
316         featureConfigs=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ -type f -maxdepth 1 2> /dev/null)
317         for featureConfigPath in ${featureConfigs}; do
318                 ln -s -f "${featureConfigPath}" "${CONFIG}/"
319         done 
320 }
321
322 # ##########################################################
323 # enableFeatureOp(featureName): 'enable' feature operation
324 #   featureName: name of the feature
325 # ##########################################################
326 function enableFeatureOp()
327 {
328         if [[ ${DEBUG} == y ]]; then
329                 echo "-- ${FUNCNAME[0]} $@ --"
330                 set -x
331         fi
332         
333         local featureName="$1"
334         
335         if [[ -z ${featureName} ]]; then
336                 echo "WARN: no feature name"
337                 return 1
338         fi
339         
340         enableScript="${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"/enable
341         if [[ -f ${enableScript} ]]; then
342                 (
343                         cd "${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"
344                         chmod u+x enable
345                         ./enable
346                 )
347         fi
348 }
349
350 # ##########################################################
351 # enableFeature(featureName, featureJar):  enables a feature
352 #   featureName: name of the feature
353 #   featureJar:  path to feature jar implementation
354 # ##########################################################
355 function enableFeature()
356 {
357         if [[ $DEBUG == y ]]; then
358                 echo "-- ${FUNCNAME[0]} $@ --"
359                 set -x
360         fi
361         
362         local featureName="$1"
363         local featureJar="$2"
364         
365         if [[ -z ${featureName} ]]; then
366                 echo "WARN: no feature name"
367                 return 1
368         fi
369         
370         if [[ -z ${featureJar} ]]; then
371                 echo "WARN: no feature jar"
372                 return 2
373         fi
374         
375         if ! depEnableAnalysis "${featureName}"; then
376                 return 3
377         fi
378         
379         if ! configEnableAnalysis "${featureName}"; then
380                 return 4
381         fi
382         
383         # enable feature itself
384
385         ln -s -f "${featureJar}" "${LIB}/"
386                 
387         # enable dependent libraries if any
388         
389         enableFeatureDeps "${featureName}"
390         
391         # enable configuration
392
393         enableFeatureConfig "${featureName}" 
394         
395         # TODO: run feature install DB scripts if any
396
397         # run custom enable if any
398
399         enableFeatureOp "${featureName}"
400 }
401
402 # ##########################################################
403 # disableFeatureDeps(featureName):  
404 #                       disables feature dependencies
405 # ##########################################################
406 function disableFeatureDeps()
407 {
408         if [[ ${DEBUG} == y ]]; then
409                 echo "-- ${FUNCNAME[0]} $@ --"
410                 set -x
411         fi
412         
413         local featureName="$1"
414         local xDepsEnabledMap featureBaseDirs aFeatureDir aFeatureName
415         local featureDeps aFeatureDep 
416         local depJarPath depJarName depJarRealPath
417         
418         if [[ -z ${featureName} ]]; then
419                 echo "WARN: no feature name"
420                 return 1
421         fi
422         
423         declare -A xDepsEnabledMap
424         
425         featureBaseDirs=$(ls -d "${FEATURES}"/*/ 2> /dev/null)
426         for aFeatureDir in ${featureBaseDirs}; do 
427                 aFeatureName=$(basename "${aFeatureDir}")
428                 if [[ "${aFeatureName}" == "${featureName}" ]]; then
429                         continue
430                 fi
431                 
432                 depJarPaths=$(ls "${aFeatureDir}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
433                 for depJarPath in ${depJarPaths}; do
434                         if [[ "$?" == 0 ]] ; then
435                                 depJarName=$(basename "${depJarPath}")
436                                 xDepsEnabledMap[${depJarName}]="${depJarPath}"
437                         fi
438                 done
439         done
440         
441         if [[ ${DEBUG} == y ]]; then
442                 echo "${!xDepsEnabledMap[@]}"
443                 echo "${xDepsEnabledMap[@]}"
444         fi
445         
446         featureDeps=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
447         for aFeatureDep in ${featureDeps}; do
448                 depJarName=$(basename "${aFeatureDep}")
449                 if [[ -L "${LIB}"/"${depJarName}" ]]; then
450                         depJarRealPath=$(readlink -f "${LIB}"/"${depJarName}")
451                         if [[ "${depJarRealPath}" == "${aFeatureDep}" ]]; then
452                                 rm -f "${LIB}"/"${depJarName}"
453                                 
454                                 # case there were multiple features using this library
455                                 # re-enable link fron an enabled feature
456                 
457                                 if [[ -n ${xDepsEnabledMap[${depJarName}]} ]]; then
458                                         ln -s -f "${xDepsEnabledMap[${depJarName}]}" "${LIB}/"
459                                 fi
460                         fi
461                 fi              
462         done
463 }
464
465 # ##########################################################
466 # disableFeatureConfig(featureName):  
467 #                               disables feature configuration
468 #   featureName: name of the feature
469 # ##########################################################
470 function disableFeatureConfig()
471 {
472         if [[ ${DEBUG} == y ]]; then
473                 echo "-- ${FUNCNAME[0]} $@ --"
474                 set -x
475         fi
476         
477         local featureName="$1"
478         local featureConfigs featureConfigPath
479         
480         if [[ -z ${featureName} ]]; then
481                 echo "WARN: no feature name"
482                 return 1
483         fi
484         
485         featureConfigs=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ -type f -maxdepth 1 2> /dev/null)
486         for featureConfigPath in ${featureConfigs}; do
487                 configFileName=$(basename "${featureConfigPath}")
488                 rm -f "${CONFIG}"/"${configFileName}" 2> /dev/null
489         done 
490 }
491
492 # ##########################################################
493 # disableFeatureOp(featureName): 'enable' feature operation
494 #   featureName: name of the feature
495 # ##########################################################
496 function disableFeatureOp()
497 {
498         if [[ ${DEBUG} == y ]]; then
499                 echo "-- ${FUNCNAME[0]} $@ --"
500                 set -x
501         fi
502         
503         local featureName="$1"
504         
505         if [[ -z ${featureName} ]]; then
506                 echo "WARN: no feature name"
507                 return 1
508         fi
509         
510         disableScript="${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"/disable
511         if [[ -f ${disableScript} ]]; then
512                 (
513                         cd "${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"
514                         chmod u+x disable
515                         ./disable
516                 )
517         fi
518 }
519
520 # ##########################################################
521 # disableFeature(featureName, featureJar):  enables a feature
522 #   featureName: name of the feature
523 # ##########################################################
524 function disableFeature()
525 {
526         if [[ ${DEBUG} == y ]]; then
527                 echo "-- ${FUNCNAME[0]} $@ --"
528                 set -x
529         fi
530         
531         local featureName="$1"
532         
533         if [[ -z ${featureName} ]]; then
534                 echo "WARN: no feature name"
535                 return
536         fi
537         
538         # disable feature itself
539
540         (
541         cd "${LIB}"
542         rm -f feature-"${featureName}"-[0-9]*.jar 2> /dev/null
543         )
544                 
545         # disable dependencies if any
546
547         disableFeatureDeps "${featureName}"
548         
549         # disable configuration if any
550
551         disableFeatureConfig "${featureName}"
552         
553         # run feature uninstall DB scripts if any
554         # TODO: future
555
556         # run custom disable if any
557         disableFeatureOp "${featureName}"
558 }
559
560 case "$1" in
561         status)
562         {
563                 # dump out status information
564                 status
565         };;
566
567         enable)
568         {
569                 if [[ -f "${POLICY_HOME}"/PID ]]; then
570                         echo "ERROR: enable: not allowed when policy is running .."
571                         echo
572                         status
573                         exit 10
574                 fi
575                 
576                 # enable the specified options
577                 shift
578                 match=
579                 for name in "$@" ; do
580                         # look for matches - 'file' has the full path name
581                         file=$(ls "${FEATURES}"/"${name}"/"${FEATURE_LIB}"/feature-"${name}"-[0-9]*.jar 2> /dev/null)
582                         if [[ "$?" != 0 ]] ; then
583                                 # no matching file
584                                 echo "${name}:  no such option"
585                         else
586                                 # make sure there is only one feature jar
587                                 countFeatureJars=$(echo "${file}" | wc -w)
588                                 if [[ ${countFeatureJars} != 1 ]]; then
589                                         echo "WARNING: skipping ${name},  ${countFeatureJars} feature libraries found"
590                                         continue
591                                 fi                      
592                                 
593                                 # found a match (handle multiple matches, just in case)
594                                 match=true
595                                 
596                                 enableFeature "${name}" "${file}"
597                         fi
598                 done
599                 if [[ "${match}" ]] ; then
600                         echo
601                         status
602                 fi
603         };;
604
605         disable)
606         {
607                 if [[ -f "${POLICY_HOME}"/PID ]]; then
608                         echo "ERROR: disable: not allowed when policy is running .."
609                         echo
610                         status
611                         exit 11
612                 fi
613                 
614                 # disable the specified options
615                 shift
616                 match=
617                 for name in "$@" ; do
618                         # look for matches -- 'file' has the last segment of the path name
619                         file=$(ls "${FEATURES}"/"${name}"/"${FEATURE_LIB}"/feature-"${name}"-[0-9]*.jar 2> /dev/null)
620                         if [[ "$?" != 0 ]] ; then
621                                 echo "${name}:  no such option"
622                         else
623                                 # found a match (handle multiple matches, just in case)
624                                 match=true
625                                 
626                                 disableFeature "${name}"
627                         fi
628                 done
629                 if [[ "${match}" ]] ; then
630                         echo
631                         status
632                 fi
633         };;
634
635         *)
636         {
637                 usage
638         };;
639 esac
640 exit