WebSphere Portal: Update/Delete a War - websphere

I need to update a portlet on the WebSphere Portal 6.0. I have tried to use xmlaccess.bat. Here is my DeployPortlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<request
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="PortalConfig_1.4.xsd"
type="update"
create-oids="true">
<portal action="locate">
<!-- The uid must match uid attribute of portlet-app in portlet.xml. -->
<web-app action="update" active="true" uid="com.firstlinesoftware.oo.portlet.TestPortlet
<url>file:///$server_root$/installableApps/TestPortlet.war</url>
<!-- The uid must match uid attribute of concrete-portlet-app in portlet.xml. -->
<portlet-app action="update" active="true" uid="TestPortlet">
<!-- The name attribute must match content of portlet-name subtag of concrete-portlet in portlet.xml. -->
<portlet action="update" active="true" objectid="theIbmPortletApiPortlet" name="TestPortlet"/>
</portlet-app>
</web-app>
<!-- Parent element under which the new page is inserted -->
<content-node action="locate" objectid="parentPage" uniquename="ibm.portal.rational.portlets"/>
<!-- The new page.
The contentparentref attribute must match the objectid of the parent.
Change the uniquename attribute to create another page. -->
<content-node action="update" uniquename="ibm.portal.TestPortletPage" ordinal="last" content-parentref="parentPage" active="true" allportletsallowed="false" create-type="explicit" type="page">
<supported-markup markup="html" update="set"/>
<localedata locale="en"><title>TestPortletPage</title></localedata>
<component action="update" ordinal="100" type="container" orientation="H">
<component action="update" ordinal="100" type="control">
<!-- The portletref must match the objectid attribute of the portlet -->
<portletinstance action="update" portletref="theIbmPortletApiPortlet"/>
</component>
</component>
</content-node>
</portal>
When I use this script for the first time everything is ok. But when I try to update the portlet with this script (everywhere action="update") the exception occure: DuplicateAppException.
Then I have tried to delete this portlet via the script:
<?xml version="1.0" encoding="UTF-8"?>
<request
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="PortalConfig_1.4.xsd"
type="update"
create-oids="true">
<!-- sample for uninstalling a web module -->
<portal action="locate">
<!-- uid must match uid attribute of portlet-app in portlet.xml -->
<web-app action="delete" active="true" uid="TestPortlet">
</web-app>
</portal>
</request>
but the warning occure: Can't delete the portlet(there is no such a web module) maybe it was deleted earlier. Actually this war file is deployed (checked this with an administration console)
Can anybody, please, help me?

I typically don't do this using xmlaccess (couldn't tell you how). I redeploy the portlet application (war or ear depending on how you package it) as I would any application in WAS. Either through the admin console, or using wsadmin. It shouldn't be a problem for you to do it that way since portlet registrations are maintained over redeploys. Here is a sample jython script for deploying an app using wsadmin. It works both standalone and clustered (connect to the primary node).
import sys
import time
def wsadminToList(inStr):
outList=[]
if (len(inStr)>0 and inStr[0]=='[' and inStr[-1]==']'):
tmpList = inStr[1:-1].split() #splits space-separated lists,
else:
tmpList = inStr.split("\n") #splits for Windows or Linux
for item in tmpList:
item = item.rstrip(); #removes any Windows "\r"
if (len(item)>0):
outList.append(item)
return outList
#endDef
def installPortalApp(earFileName, appName, cellName, clusterName, installOptions):
#--------------------------------------------------------------
# set up globals
#--------------------------------------------------------------
global AdminApp
global AdminControl
global AdminConfig
global Help
installOptions.append('-appname')
installOptions.append(appName)
# Should we install on a cluster?
if len(clusterName) != 0:
appServer = 'WebSphere:cell=' + cellName + ',cluster=' + clusterName
mapModuleOptions = [[ '.*', '.*', appServer ]]
# Append additional options
installOptions.append('-cluster')
installOptions.append(clusterName)
AdminApp.install(earFileName, installOptions)
AdminConfig.save( )
count = 0
# This is probably not necessary
while not AdminApp.isAppReady(appName) and count < 10:
count = count + 1
print 'Waiting for app to be ready ' + count + ' of 10'
time.sleep(10)
#endWhile
clusterId = AdminConfig.getid('/ServerCluster:' + clusterName + '/' )
print 'clusterId' + clusterId
clusterMembers = wsadminToList(AdminConfig.list('ClusterMember', clusterId))
for member in clusterMembers:
print 'startApplication on member ' + str(member)
currentServer = AdminConfig.showAttribute(member, 'memberName')
print 'currentServer ' + currentServer
currentNodeName = AdminConfig.showAttribute(member, 'nodeName')
print 'currentNodeName ' + currentNodeName
query = 'cell=' + cellName + ',node=' + currentNodeName + ',type=ApplicationManager,process=' + currentServer + ',*'
print 'query ' + query
appMgr = AdminControl.queryNames(query )
print appMgr
Sync1 = AdminControl.completeObjectName('type=NodeSync,node=' + currentNodeName + ',*')
print 'Sync1 ' + Sync1
AdminControl.invoke(Sync1, 'sync')
print 'Node synchronized. Waiting a short while for binary expansion to finish'
time.sleep(5)
print 'Starting application'
AdminControl.invoke(appMgr, "startApplication", appName )
#endFor
else:
appMgr = AdminControl.queryNames("type=ApplicationManager,*" )
AdminApp.install(earFileName, installOptions)
AdminConfig.save( )
AdminControl.invoke(appMgr, "startApplication", appName )
#endIf
#endDef
#if (len(sys.argv) != 4 and len(sys.argv) != 5):
# print len(sys.argv)
# print "install_application_ear.py: this script requires the following parameters: ear file name, application name, cell name, install options and cluster name (optional)"
# sys.exit(1)
#endIf
earFileName = sys.argv[0]
print 'earFileName' + earFileName
appName = sys.argv[1]
cellName = sys.argv[2]
installOptions = eval(sys.argv[3])
clusterName = ""
if len(sys.argv) == 5:
clusterName = sys.argv[4]
installPortalApp(earFileName, appName, cellName, clusterName, installOptions)

Lets start from the end: the reason that your action=delete doesn't work is because you're referring to the webapp with an incorrect uid. During installation, you assign it the uid com.firstlinesoftware.oo.portlet.TestPortlet, and during deletion, you're referring to TestPortlet. That's not going to work out.
I programmed an automated system that redeploys portlet applications and it's been used for years with no issues, so something must be wrong in your XMLAccess file. Lets work through it. Can you start by removing the portlet-app child element altogether from the web-app element? is there a reason why you need it there?

Related

How to uninstall an application that is already stopped

The problem is that if the application is "stopped" this will return nothing. But i still want to uninstall it anyway. I don't know the application name, i'm getting all applications installed on a Server and then uninstalling them all.
apps = AdminControl.queryNames('type=Application,node=' + nodeName + ',process=' + serverName + ',*').split()
Here is my code.
serverObj = AdminControl.completeObjectName('type=Server,node=%s,name=%s,*' % (nodeName, serverName))
serverID = AdminConfig.getid('/Node:%s/Server:%s/' % (nodeName, serverName))
if serverID == "":
print "Can't find the server, exiting..."
sys.exit(1)
else:
cellName = AdminControl.getAttribute(serverObj, 'cellName')
#Uninstall Apps
apps = AdminControl.queryNames('type=Application,node=' + nodeName + ',process=' + serverName + ',*').split()
appManager=AdminControl.queryNames('type=ApplicationManager,node=' + nodeName + ',process=,*')
if len(apps) > 0:
for app in apps:
appName = AdminControl.getAttribute(app, 'name')
AdminControl.invoke(appManager,'stopApplication', appName)
print "Uninstalling application: " + appName
AdminApp.uninstall(appName)
else:
print "No applications to uninstall"
You can use the below snippet to uninstall all Apps deployed on the target server:
#Get the list of all Apps deployed in target server
installedApps=AdminApp.list("WebSphere:cell=%s,node=%s,server=%s" % (cellName, nodeName, serverName))
#Check if there are any installed Apps on the server
if len (installedApps) > 0:
#if there are installed Apps, iterate through the list and uninstall Apps one by one
for app in installedApps.splitlines():
print "uninstalling "+ app +" ...."
AdminApp.uninstall(app)
#Save the changes
AdminConfig.save()
else:
#if there are no installed Apps, do nothing
print "No applications to uninstall"
You can use AdminApp.list() to obtain the list of apps for a target scope. So for server scope:
AdminApp.list("WebSphere:cell=yourCellName,node=yourNodeName,servers=yourServerNameā€¯)
With that information, you can then use AdminApp.uninstall() to uninstall the app, for example:
AdminApp.uninstall('NameOfApp')

Swagger schema for aws lambda

I am using AWS version 4 signing process for creating signature for AWS lambda service with API ListFunctions.I am getting correct URL which on postman worked.But when running that python file I am getting 403 status error which tells "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.".Can anyone help me solve the issue?thanks in advance!!
python file :
# Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# This file is licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
#
# ABOUT THIS PYTHON SAMPLE: This sample is part of the AWS General Reference
# Signing AWS API Requests top available at
# https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html
#
# AWS Version 4 signing example
# EC2 API (DescribeRegions)
# See: http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
# This version makes a GET request and passes the signature
# in the Authorization header.
import sys, os, base64, datetime, hashlib, hmac
import requests # pip install requests
# ************* REQUEST VALUES *************
method = 'GET'
service = 'lambda'
host = 'lambda.us-east-1.amazonaws.com'
region = 'us-east-1'
endpoint = 'https://lambda.us-east-1.amazonaws.com/2015-03-31/functions'
request_parameters = 'Action=ListFunctions&Version=2015-03-31'
# Key derivation functions. See:
# http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python
def sign(key, msg):
return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
def getSignatureKey(key, dateStamp, regionName, serviceName):
kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
kRegion = sign(kDate, regionName)
kService = sign(kRegion, serviceName)
kSigning = sign(kService, 'aws4_request')
return kSigning
# Read AWS access key from env. variables or configuration file. Best practice is NOT
# to embed credentials in code.
access_key = ""
secret_key = ""
if access_key is None or secret_key is None:
print('No access key is available.')
sys.exit()
# Create a date for headers and the credential string
t = datetime.datetime.utcnow()
amzdate = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope
# ************* TASK 1: CREATE A CANONICAL REQUEST *************
# http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
# Step 1 is to define the verb (GET, POST, etc.)--already done.
# Step 2: Create canonical URI--the part of the URI from domain to query
# string (use '/' if no path)
canonical_uri = '/'
# Step 3: Create the canonical query string. In this example (a GET request),
# request parameters are in the query string. Query string values must
# be URL-encoded (space=%20). The parameters must be sorted by name.
# For this example, the query string is pre-formatted in the request_parameters variable.
canonical_querystring = request_parameters
# Step 4: Create the canonical headers and signed headers. Header names
# must be trimmed and lowercase, and sorted in code point order from
# low to high. Note that there is a trailing \n.
canonical_headers = 'host:' + host + '\n' + 'x-amz-date:' + amzdate + '\n'
# Step 5: Create the list of signed headers. This lists the headers
# in the canonical_headers list, delimited with ";" and in alpha order.
# Note: The request can include any headers; canonical_headers and
# signed_headers lists those that you want to be included in the
# hash of the request. "Host" and "x-amz-date" are always required.
signed_headers = 'host;x-amz-date'
# Step 6: Create payload hash (hash of the request body content). For GET
# requests, the payload is an empty string ("").
payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()
# Step 7: Combine elements to create canonical request
canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash
# ************* TASK 2: CREATE THE STRING TO SIGN*************
# Match the algorithm to the hashing algorithm you use, either SHA-1 or
# SHA-256 (recommended)
algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
string_to_sign = algorithm + '\n' + amzdate + '\n' + credential_scope + '\n' + hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()
# ************* TASK 3: CALCULATE THE SIGNATURE *************
# Create the signing key using the function defined above.
signing_key = getSignatureKey(secret_key, datestamp, region, service)
# Sign the string_to_sign using the signing_key
signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
# ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
# The signing information can be either in a query string value or in
# a header named Authorization. This code shows how to use a header.
# Create authorization header and add to request headers
authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
# The request can include any headers, but MUST include "host", "x-amz-date",
# and (for this scenario) "Authorization". "host" and "x-amz-date" must
# be included in the canonical_headers and signed_headers, as noted
# earlier. Order here is not significant.
# Python note: The 'host' header is added automatically by the Python 'requests' library.
headers = {'x-amz-date':amzdate, 'Authorization':authorization_header}
print(headers)
# ************* SEND THE REQUEST *************
request_url = endpoint + '?' + canonical_querystring
print('\nBEGIN REQUEST++++++++++++++++++++++++++++++++++++')
print('Request URL = ' + request_url)
r = requests.get(request_url, headers=headers)
print('\nRESPONSE++++++++++++++++++++++++++++++++++++')
print('Response code: %d\n' % r.status_code)
print(r.text)
The problem is you didn't set up AWS Secret Access Key properly.
Solution:
Go to IAM section of your AWS account and select user or create one.
Assign specific roles needed for the project.
Navigate to Security credentials tab in your user account.
Select existing key or create new one and find AWS Secret Access Key.
You can setup AWS Secret Access Key as environmental varialbe in your system or in code.

Changing container managed authentification alias

I'm using WebSphere 7.0.0.37 and jython
I need to change the 'Container-managed authentication alias', unfortunatelly I can't find anything in API, inspecting attributes of existing DataSources or any example for that task.
I have succesfully changed the 'composant-managed authentication alias' with:
AdminConfig.modify(DataSourceProvider, '[[name "basename"] [authDataAlias "' + nameNode + '/' + aliasJaas + '" ] ')
How can i do that?
thank you!
Here is some logic which you could use to solve your problem.
# Create new alias
cellName = AdminConfig.showAttribute(AdminConfig.list("Cell"), "name")
security = AdminConfig.getid('/Cell:' + cellName + '/Security:/')
myAlias = 'blahAlias'
user = 'blah'
pswd = 'blah'
jaasAttrs = [['alias', myAlias], ['userId', user], ['password', pswd ]]
print AdminConfig.create('JAASAuthData', security, jaasAttrs)
print "Alias = " + myAlias + " was created."
# Get a reference to your DataSource (assume you know how to do this):
myDS = ...
# Set new alias on DataSource
AdminConfig.modify('MappingModule', myDS, '[[authDataAlias ' + myAlias + '] [mappingConfigAlias DefaultPrincipalMapping]]')
Note that if you can figure out how to do a given task in the Admin Console, you can use the "Command Assist" function to get a Jython snippet to do the equivalent via wsadmin. See here.

Error in Python when communicating with AWS

I have this code, am not sure why the security group is not recognized :
rs = client.get_all_security_groups()
print rs
SecurityGroup:default
req=client.request_spot_instances(price= 0.5,
image_id=config.get('EC2', 'ami'),
instance_type=config.get('EC2', 'type'),
key_name=config.get('EC2', 'key_pair'),
user_data='',
security_groups='default')[0]
<?xml version="1.0" encoding="UTF-8"?>
<Response><Errors><Error><Code>InvalidParameterValue</Code>
<Message>
Value () for parameter groupId is invalid. The value cannot be empty</Message></Error></Errors>
<RequestID>a50166a5-3c30-4572-9474-ec46d6a978d0</RequestID></Response>
I
You need to set security group id, not security group name
rs = client.get_all_security_groups()
print rs
SecurityGroup:default
req=client.request_spot_instances(price= 0.5,
image_id=config.get('EC2', 'ami'),
instance_type=config.get('EC2', 'type'),
key_name=config.get('EC2', 'key_pair'),
user_data='',
security_groups=rs.id)[0]

Attaching shared-libs to WebSphere application's module

Based on IBM documentation, I wrote a jython script that adds shared libs to an existing application.
# Application name
app = sys.argv[0]
dep = AdminConfig.getid('/Deployment:' + app + '/')
depObject = AdminConfig.showAttribute(dep, 'deployedObject')
classldr = AdminConfig.showAttribute(depObject, 'classloader')
for x in range(1, len(sys.argv)):
AdminConfig.create('LibraryRef', classldr,
[['libraryName', sys.argv[x]], ['sharedClassloader', 'true']])
AdminConfig.save()
Unfortunately, this is setting the shared library only for the application and not for the modules. How could I achieve setting the libraries for both ?
I tried to get the modules of an application but I cannot get the classloader of it.
BTW, what is the sharedClassloader attributes used for ?
Note: I know this is bad practice, but I inherited a bunch of legacy applications, so please don't advice to get rid of shared libs or to add a deployment.xml
Well, here is the working script addSharedLibrary.py <application-name> shared-lib [shared-lib...]
def addSharedLibrary(holder):
classldr = AdminConfig.showAttribute(holder, 'classloader')
for x in range(1, len(sys.argv)):
AdminConfig.create('LibraryRef', classldr, [['libraryName', sys.argv[x]], ['sharedClassloader', 'true']])
def handleWebModules(applicationName):
webModules = AdminConfig.list('WebModuleDeployment').split('\n')
for webModule in webModules:
if (webModule.find(applicationName) != -1):
print 'Setting for ' + webModule
addSharedLibrary(webModule)
dep = AdminConfig.getid('/Deployment:' + sys.argv[0] + '/')
addSharedLibrary(AdminConfig.showAttribute(dep, 'deployedObject'))
handleWebModules(app)
AdminConfig.save()
I think a good way to accomplish this is to create a shared library at the server level, and then create a classloader also on the server level in order to load the libraries.
set serv [$AdminConfig getid /Cell:mycell/Node:mynode/Server:server1/]
print AdminConfig.create('Library', serv, [['name', 'mySharedLibrary'], ['classPath',
'home/myProfile/mySharedLibraryClasspath']])
AdminConfig.create('Library', serv, [['name', 'mySharedLibrary'],
['classPath','test1.jar;test2.jar;test3.jar']])
appServer = AdminConfig.list('ApplicationServer', serv)
print appServer
classLoad = AdminConfig.showAttribute(appServer, 'classloaders')
cleanClassLoaders = classLoad[1:len(classLoad)-1]
classLoader1 = cleanClassLoaders.split(' ')[0]
classLoader1 = AdminConfig.create('Classloader', appServer, [['mode', 'PARENT_FIRST']])
print AdminConfig.create('LibraryRef', classLoader1, [['libraryName', 'MyshareLibrary']])
AdminConfig.save()
AdminNodeManagement.syncActiveNodes()
Thanks poussma for your jython script, it works on the previous version of WAS...
so i adjusted your code to make it work also on WAS8 :
Run the cmd line with : addSharedLibrary.py <application-name> [shared-lib...]
def addSharedLibrary(holder):
classldr = AdminConfig.showAttribute(holder, 'classloader')
for x in range(1, len(sys.argv)):
AdminConfig.create('LibraryRef', classldr, [['libraryName', sys.argv[x]], ['sharedClassloader', 'true']])
def handleWebModules(applicationName):
webModules = AdminConfig.list('WebModuleDeployment').split('\r')
webModules = map(lambda s: s.strip(), webModules)
for webModule in webModules:
if (webModule.find(applicationName+'.ear') != -1):
print 'Setting for ' + webModule
addSharedLibrary(webModule)
dep = AdminConfig.getid('/Deployment:' + sys.argv[0] + '/')
addSharedLibrary(AdminConfig.showAttribute(dep, 'deployedObject'))
handleWebModules(sys.argv[0])
AdminConfig.save()

Resources