1
1
"""
2
- Copyright (c) 2017, 2019 , Oracle Corporation and/or its affiliates. All rights reserved.
2
+ Copyright (c) 2017, 2020 , Oracle Corporation and/or its affiliates. All rights reserved.
3
3
Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
4
"""
5
5
import copy
6
6
import os
7
7
from java .io import ByteArrayOutputStream
8
8
from java .io import File
9
+ from java .io import FileInputStream
9
10
from java .io import FileNotFoundException
10
11
from java .io import IOException
11
12
from java .lang import IllegalStateException
12
13
from java .security import NoSuchAlgorithmException
13
14
from java .util .jar import JarFile
15
+ from java .util .jar import Manifest
14
16
from java .util .zip import ZipException
15
17
from sets import Set
16
18
from wlsdeploy .aliases .location_context import LocationContext
@@ -164,7 +166,7 @@ def __add_applications(self):
164
166
165
167
if deployer_utils .is_path_into_archive (app_source_path ):
166
168
if self .archive_helper is not None :
167
- self .archive_helper . extract_file (app_source_path )
169
+ self .__extract_source_path_from_archive (app_source_path , APPLICATION , application_name )
168
170
else :
169
171
ex = exception_helper .create_deploy_exception ('WLSDPLY-09303' , application_name )
170
172
self .logger .throwing (ex , class_name = self ._class_name , method_name = _method_name )
@@ -567,14 +569,23 @@ def __build_app_deploy_strategy(self, location, model_apps, existing_apps, exist
567
569
self .model_context .replace_tokens (APPLICATION , app , param , app_dict )
568
570
569
571
if app in existing_apps :
572
+ # Compare the hashes of the domain's existing apps to the model's apps.
573
+ # If they match, remove them from the list to be deployed.
574
+ # If they are different, stop and un-deploy the app, and leave it in the list.
575
+
570
576
existing_app_ref = dictionary_utils .get_dictionary_element (existing_app_refs , app )
571
577
plan_path = dictionary_utils .get_element (existing_app_ref , 'planPath' )
572
578
src_path = dictionary_utils .get_element (existing_app_ref , 'sourcePath' )
573
579
574
- model_src_hash = \
575
- self .__get_hash (dictionary_utils .get_element (app_dict , SOURCE_PATH ))
576
- model_plan_hash = \
577
- self .__get_hash (dictionary_utils .get_element (app_dict , PLAN_PATH ))
580
+ model_src_path = dictionary_utils .get_element (app_dict , SOURCE_PATH )
581
+
582
+ if (model_src_path is not None ) and deployer_utils .is_path_into_archive (model_src_path ) \
583
+ and self .archive_helper .contains_path (model_src_path ):
584
+ model_src_hash = - 1 # don't calculate hash, just ensure that hashes will not match
585
+ else :
586
+ model_src_hash = self .__get_hash (model_src_path )
587
+
588
+ model_plan_hash = self .__get_hash (dictionary_utils .get_element (app_dict , PLAN_PATH ))
578
589
579
590
existing_src_hash = self .__get_file_hash (src_path )
580
591
existing_plan_hash = self .__get_file_hash (plan_path )
@@ -603,6 +614,10 @@ def __get_file_hash(self, filename):
603
614
try :
604
615
if filename is None :
605
616
return None
617
+
618
+ if File (filename ).isDirectory (): # can't calculate for exploded apps, libraries, etc.
619
+ return None
620
+
606
621
hash_value = FileUtils .computeHash (filename )
607
622
except (IOException , NoSuchAlgorithmException ), e :
608
623
ex = exception_helper .create_deploy_exception ('WLSDPLY-09309' , filename , e .getLocalizedMessage (), error = e )
@@ -734,7 +749,8 @@ def __deploy_model_applications(self, model_apps, app_location, deployed_applist
734
749
options = _get_deploy_options (model_apps , app_name , library_module = 'false' )
735
750
for uses_path_tokens_attribute_name in uses_path_tokens_attribute_names :
736
751
if uses_path_tokens_attribute_name in app_dict :
737
- self .__extract_file_from_archive (app_dict [uses_path_tokens_attribute_name ])
752
+ self .__extract_source_path_from_archive (app_dict [uses_path_tokens_attribute_name ],
753
+ APPLICATION , app_name )
738
754
739
755
location .add_name_token (token_name , app_name )
740
756
resource_group_template_name , resource_group_name , partition_name = \
@@ -823,6 +839,31 @@ def __extract_file_from_archive(self, path):
823
839
self .archive_helper .extract_file (path )
824
840
return
825
841
842
+ def __extract_source_path_from_archive (self , source_path , model_type , model_name ):
843
+ """
844
+ Extract contents from the archive set for the specified source path.
845
+ The contents may be a single file, or a directory with exploded content.
846
+ :param source_path: the path to be extracted (previously checked to be under wlsdeploy)
847
+ :param model_type: the model type (Application, etc.), used for logging
848
+ :param model_name: the element name (my-app, etc.), used for logging
849
+ """
850
+ _method_name = '__extract_source_path_from_archive'
851
+
852
+ # source path may be may be a single file (jar, war, etc.)
853
+ if self .archive_helper .contains_file (source_path ):
854
+ self .archive_helper .extract_file (source_path )
855
+
856
+ # source path may be exploded directory in archive
857
+ elif self .archive_helper .contains_path (source_path ):
858
+ self .archive_helper .extract_directory (source_path )
859
+
860
+ else :
861
+ ex = exception_helper .create_deploy_exception ('WLSDPLY-09330' , model_type , model_name , source_path )
862
+ self .logger .throwing (ex , class_name = self ._class_name , method_name = _method_name )
863
+ raise ex
864
+
865
+ return
866
+
826
867
def __get_deployable_library_versioned_name (self , source_path , model_name ):
827
868
"""
828
869
Get the proper name of the deployable library that WLST requires in the target domain. This method is
@@ -840,49 +881,28 @@ def __get_deployable_library_versioned_name(self, source_path, model_name):
840
881
841
882
old_name_tuple = deployer_utils .get_library_name_components (model_name , self .wlst_mode )
842
883
try :
884
+ versioned_name = old_name_tuple [self ._EXTENSION_INDEX ]
843
885
source_path = self .model_context .replace_token_string (source_path )
844
- archive = JarFile (source_path )
845
- manifest_object = archive .getManifest ()
846
- tokens = []
847
- if manifest_object is not None :
848
- bao = ByteArrayOutputStream ()
849
- manifest_object .write (bao )
850
- manifest = bao .toString ('UTF-8' )
851
- tokens = manifest .split ()
852
-
853
- if 'Extension-Name:' in tokens :
854
- extension_index = tokens .index ('Extension-Name:' )
855
- if len (tokens ) > extension_index :
856
- versioned_name = tokens [extension_index + 1 ]
857
- else :
858
- ex = exception_helper .create_deploy_exception ('WLSDPLY-09321' , model_name , source_path , tokens )
859
- self .logger .throwing (ex , class_name = self ._class_name , method_name = _method_name )
860
- raise ex
861
- else :
862
- versioned_name = old_name_tuple [self ._EXTENSION_INDEX ]
886
+ manifest = self .__get_manifest (source_path )
887
+ if manifest is not None :
888
+ attributes = manifest .getMainAttributes ()
889
+
890
+ extension_name = attributes .getValue ("Extension-Name" )
891
+ if not string_utils .is_empty (extension_name ):
892
+ versioned_name = extension_name
863
893
864
- if 'Specification-Version:' in tokens :
865
- spec_index = tokens .index ('Specification-Version:' )
866
- if len (tokens ) > spec_index :
867
- versioned_name += '#' + tokens [spec_index + 1 ]
894
+ specification_version = attributes .getValue ("Specification-Version" )
895
+ if not string_utils .is_empty (specification_version ):
896
+ versioned_name += '#' + specification_version
868
897
869
898
# Cannot specify an impl version without a spec version
870
- if 'Implementation-Version:' in tokens :
871
- impl_index = tokens .index ('Implementation-Version:' )
872
- if len (tokens ) > impl_index :
873
- versioned_name += '@' + tokens [impl_index + 1 ]
874
- else :
875
- ex = exception_helper .create_deploy_exception ('WLSDPLY-09322' , model_name ,
876
- source_path , tokens )
877
- self .logger .throwing (ex , class_name = self ._class_name , method_name = _method_name )
878
- raise ex
879
- else :
880
- ex = exception_helper .create_deploy_exception ('WLSDPLY-09323' , model_name , source_path , tokens )
881
- self .logger .throwing (ex , class_name = self ._class_name , method_name = _method_name )
882
- raise ex
899
+ implementation_version = attributes .getValue ("Implementation-Version" )
900
+ if not string_utils .is_empty (implementation_version ):
901
+ versioned_name += '@' + implementation_version
902
+
903
+ self .logger .info ('WLSDPLY-09324' , model_name , versioned_name ,
904
+ class_name = self ._class_name , method_name = _method_name )
883
905
884
- self .logger .info ('WLSDPLY-09324' , model_name , versioned_name ,
885
- class_name = self ._class_name , method_name = _method_name )
886
906
except (IOException , FileNotFoundException , ZipException , IllegalStateException ), e :
887
907
ex = exception_helper .create_deploy_exception ('WLSDPLY-09325' , model_name , source_path , str (e ), error = e )
888
908
self .logger .throwing (ex , class_name = self ._class_name , method_name = _method_name )
@@ -912,8 +932,8 @@ def __get_deployable_application_versioned_name(self, source_path, model_name):
912
932
913
933
try :
914
934
source_path = self .model_context .replace_token_string (source_path )
915
- archive = JarFile (source_path )
916
- manifest = archive . getManifest ()
935
+ manifest = self . __get_manifest (source_path )
936
+
917
937
if manifest is not None :
918
938
attributes = manifest .getMainAttributes ()
919
939
application_version = attributes .getValue (self ._APP_VERSION_MANIFEST_KEY )
@@ -930,6 +950,37 @@ def __get_deployable_application_versioned_name(self, source_path, model_name):
930
950
self .logger .exiting (class_name = self ._class_name , method_name = _method_name , result = versioned_name )
931
951
return versioned_name
932
952
953
+ def __get_manifest (self , source_path ):
954
+ """
955
+ Returns the manifest object for the specified path.
956
+ The source path may be a jar, or an exploded path.
957
+ :param source_path: the source path to be checked
958
+ :return: the manifest, or None if it is not present
959
+ :raises: IOException: if there are problems reading an existing manifest
960
+ """
961
+ source_path_file = File (source_path )
962
+ manifest = None
963
+
964
+ if source_path_file .isDirectory ():
965
+ manifest_file = File (source_path_file , "META-INF/MANIFEST.MF" )
966
+ if manifest_file .exists ():
967
+ stream = None
968
+ try :
969
+ stream = FileInputStream (manifest_file )
970
+ manifest = Manifest (stream )
971
+ finally :
972
+ if stream is not None :
973
+ try :
974
+ stream .close ()
975
+ except IOException :
976
+ # nothing to report
977
+ pass
978
+ else :
979
+ archive = JarFile (source_path )
980
+ manifest = archive .getManifest ()
981
+
982
+ return manifest
983
+
933
984
def __get_deployment_ordering (self , apps ):
934
985
_method_name = '__get_deployment_ordering'
935
986
name_sorted_keys = apps .keys ()
0 commit comments