Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
5/26/2018
1
© 2017 International Business Machines Corporation
Connecting to IBM i from Open Source
Jesse R. Gorzinski, MBA (and sometimes Aaron Bartell)Business [email protected] / [email protected]
© 2017 International Business Machines Corporation
Agenda
• Why this matters...
• Connecting with Watson
• Connecting to IBM i from Open Source
– Same Machine
o DB2 connector/adapters
– Separate Machine
o Language toolkits
o DB2 Connect offerings
o JTOpen (IBM Toolbox for Java)
o SSH
o Node.js jdbc/jt400 packages
o MariaDB/MySQL w/storage engine
o Roll-your-own web services
o IBM DataConnect
• Working together with data queues
5/26/2018
2
© 2017 International Business Machines Corporation
Can Node.JS and Python programs
integrate with IBM i data?
YES!
• IBM i integration delivered with the languages
• Watson integration delivered with the languages
© 2017 International Business Machines Corporation
Python and Watson
• IBM has published many examples of how to talk to Watson.
– e.g. Python "Personality Insights" app
– github.com/watson-developer-cloud/personality-insights-python
5/26/2018
3
© 2017 International Business Machines Corporation
Python and Watson
© 2017 International Business Machines Corporation
Python and Watson
5/26/2018
4
© 2017 International Business Machines Corporation
Node.JS and Watson
• Personality Insights
– Node.JS version
– Output in a different format
– github.com/watson-developer-cloud/personality-insights-nodejs
© 2017 International Business Machines Corporation
Node.JS and Watson
5/26/2018
5
© 2017 International Business Machines Corporation
Node.JS and Watson
© 2017 International Business Machines Corporation
Connecting to IBM i (same machine)
5/26/2018
6
© 2017 International Business Machines Corporation
Database connectors
• Ruby
– github.com/ibmdb/ruby-ibmdb
• PHP
– php.net/manual/en/ref.pdo-ibm.php (objects)
– php.net/manual/en/book.ibm-db2.php (procedural)
• Python
– krengel.tech/dw-ibmi-python
• Node.js
– bitbucket.org/litmis/nodejs-idb-connector
© 2017 International Business Machines Corporation
Python ibm_db interface
• ibmdb project: github.com/ibmdb/python-ibmdb
• Cross-platform, open source project sponsored by IBM.
• Supports DB2 LUW, Informix, and DB2 for i using DB2 Connect on
Windows, Mac OS X, Linux, and a few other platforms
– Requires DB2 connect license (same as packages for Ruby, PHP)
• Ported to run in PASE, using PASE CLI by IBM Rochester
– Free! (same as packages for Ruby, PHP)
• Uses the Apache 2 License
• pip3 install /QOpenSys/QIBM/ProdData/OPS/Python-pkgs/ibm_db/ibm_db-*cp34*.whl
5/26/2018
7
© 2017 International Business Machines Corporation
Sample program to convert SQL output to Excel
def writeDataToExcel(args, workbook, sheetName):
""" Write query output to Excel worksheet """
try:
conn = db.connect()
cur = conn.cursor()
cur.execute(args.c)
headers = [descr[0] for descr in cur.description]
format =
workbook.add_format({'bold': args.b, 'italic': args.i})
worksheet = workbook.add_worksheet(sheetName)
worksheet.write_row('A1', headers, format)
for i, row in enumerate(cur, start=1):
worksheet.write_row(i, 0, row)
except Exception as err:
print('ERROR: ' + str(err))
© 2017 International Business Machines Corporation
Sample program to convert SQL Output to Excel
krengel.tech/seiden-dbtoxlsx
5/26/2018
8
© 2017 International Business Machines Corporation
How Does a Table Function Work?
15
UDTF Program QSQOBSTAT
SELECT *
FROM TABLE
(qsys2.object_statistics
('QSYS ','LIB '))
as x
DB2 for iFirst Call (Optional)
Final Call (Optional)
Open Call
Close Call
Fetch Calls
('QSYS ','LIB ')
02000
('QSYS ','LIB ')
Your
Query
© 2017 International Business Machines Corporation
Challenge: select with complex selection logic
• PHP serving data for mobile app
• Old table structures and relationships made for complex SQL
• RPG was easier for programmer to modify and tune than
huge SQL
• RPG (SQL and record-level) eliminated need for complicated
JOINs and WHERE clauses and the constant changes to
SQL as new requirements were discovered.– gist.github.com/alanseiden/04235490fe81a1b791ca
• Solution (Alan Seiden): UDTF presents complex logic as
simple table.
5/26/2018
9
© 2017 International Business Machines Corporation
UDTF for Mobile App
• Show daily delivery status of orders in mobile app
• Basic flow:
– Native mobile app requests data from PHP on IBM i
– PHP queries DB2 for the data
– PHP converts DB2 data to JSON for app
consumption
© 2017 International Business Machines Corporation
PHP calling the UDTF named “fnorder”
• (Alan used Zend Framework 2)
• After more manipulation in the PHP, JSON looks like this:
• gist.github.com/alanseiden/e85364ed7515bb6b5bcc
$ordNum = 12345; // parameter from app
$sql = "select * from table(fnorder( cast(? as numeric(2,0)), cast(? as char(10))
)) as order_details”;
$db = $this->getDbAdapter();$result = $db->query($sql, array(1, $ordNum))->toArray();
5/26/2018
10
db2sock
bitbucket.org/litmis/db2sock - Repo
PASE DB2 CLI asynchronous API driver and
more (libdb400.a)
The goal is new APIs for any language. To be clear, 'async' APIs are NOT
just for 'async' Node.js, but can instead be applied to all PASE langs (PHP,
Ruby, Python, etc). Some languages will use 'async' poll/reap (php), others
use async 'callback' (nodejs).
● libdb400.a should fit seamless under any existing scripting language db2
extension
● Wide APIs (UTF16) - provide all current missing libdb400.a 'wide' CLI
APIs
● Async APIs - high performing async CLI APIs for all new PASE
languages.
Status: BETA
db2sock Node.js implementation
krengel.tech/db2sock-nodejs-itoolkit - RepoStatus: BETA
// Setup the toolkit core
var tk = require("../db2sock-itoolkit");
var core = new tk.Core('http://<IP>/db2json.db2');
// Create a program call
var pgm = core.program('HELLO', 'DB2JSON');
pgm.addParam('char', '128a', 'Hi there');
core.add(pgm);
// Run the core's current call list, and get the results
var result = core.run(function (result) {
console.log('Results:');
console.log(result);
});
5/26/2018
11
db2util
bitbucket.org/litmis/db2util - Repo
Shell command DB2 access. Great for when you need to
automate with shell scripts and inevitably need to access DB2.
JSON output (-o json)
$ db2util "select CUSNUM from QCUSTCDT where LSTNAM=? or LSTNAM=?" -
p Jones Vine -o json
Result{
"records":[
{
"CUSNUM":"839283"
},
{
"CUSNUM":"392859"
}
]
}
borgi
bitbucket.org/litmis/borgi - Repo
Welcome to borgi project. Goal is chroot friendly system utility.
Run a command.
$ borgi -c "ADDLIBLE LIB(FROGNOT)"
-msgid SQL0443 -msgtype DIAGNOSTIC -msgsub *NULL -msgsev 30 -msgstamp 2017-06-
20-13.24.27.168495 -msgtolib QSYS -msgtopgm QSQRUN4 -msgtomod QSQCALLSP -
msgtoproc CLEANUP -msgtoinst 42334 -msgtxt "Trigger program or external
routine detected an error."
-msgid CPF2110 -msgtype ESCAPE -msgsub EXCEPTION HANDLED -msgsev 40 -msgstamp
2017-06-20-13.24.27.168228 -msgtolib QSYS -msgtopgm QSQRUN4 -msgtomod
QSQCALLSP -msgtoproc CALLPROGRAM -msgtoinst 43225 -msgtxt "Library FROGNOT not
found."
$ borgi -d "select LSTNAM,CITY,STREET,ZIPCOD,BALDUE from QIWS/QCUSTCDT where
LSTNAM=? or LSTNAM=?" -? Jones Vine
-LSTNAM Jones -CITY Clay -STREET "21B NW 135 St" -ZIPCOD 13041 -BALDUE 100.00
-LSTNAM Vine -CITY Broton -STREET "PO Box 79" -ZIPCOD 5046 -BALDUE 439.00
DB2 access from a shell
5/26/2018
12
© 2017 International Business Machines Corporation
Connecting to IBM i (separate machine)
© 2017 International Business Machines Corporation
Enabling easy extension of OSS for IBM i - XMLService
• Allows access to IBM i programs, service programs, shell commands, and
even DB2!
• Can be called locally or remotely, stateful or stateless, very flexible!
• Toolkits are written for several languages, to make it even easier!
24
5/26/2018
13
© 2017 International Business Machines Corporation
Language toolkits (all open source)
• Node.js: bitbucket.org/litmis/nodejs-itoolkit
• Python: bitbucket.org/litmis/python-itoolkit
• PHP: krengel.tech/php-itoolkit (seidengroup.com/toolkit)
• Ruby: bitbucket.org/litmis/ruby-itoolkit
• Swift: bitbucket.org/litmis/swift-itoolkit
• .NET: krengel.tech/dotNet-itoolkit
© 2017 International Business Machines Corporation
Python itoolkit – an XMLSERVICE wrapper
• itoolkit project: ibm.biz/itoolkitpython
• Interface to XMLService: ibm.biz/xmlservice
• Let's you call
– RPG programs and service programs
– CL commands
– PASE programs and shell scripts
– SQL database access
• pip3 install /QOpenSys/QIBM/ProdData/OPS/Python-
pkgs/itoolkit/itoolkit-*cp34*.whl
• Verify it's installed by running
python3 -c "import itoolkit; print(itoolkit.__version__)"
5/26/2018
14
© 2017 International Business Machines Corporation
What can we do?
• Commands
– iCmd – Call CL command (even with output parameters)
– iCmd5250 – call CL command and get screen output
• Programs
– iPgm – Call program
– iSrvPgm – Call service program
• Database
– iSqlQuery – call DB2 query
– iSqlPrepare, iSqlExecute
– iSqlParm
– iSqlFetch
• iSh – call PASE program or shell script
© 2017 International Business Machines Corporation
Which transport is right for you?
● iLibCall
− no configuration needed
− fastest call, directly from your job, but no isolation from bad calls
− local connection (on IBM i) only
− some things don't work from chroot
− Only support from Python, PHP
5/26/2018
15
© 2017 International Business Machines Corporation
Which transport is right for you? (cont.)
● iDB2Call
− calls over previously-discussed ibm_db
− no configuration needed
− bad calls kill QSQSRVR job, not your job
− local (free) and remote (licensed) connections supported
© 2017 International Business Machines Corporation
Which transport is right for you? (cont.)
● iRestCall
− need to configure XMLSERVICE in one of your CGI HTTP servers
− bad calls kill your FastCGI job, not your job
− local and remote connections supported
− need SSL TLS for security
5/26/2018
16
© 2017 International Business Machines Corporation
Apache configuration
# In Apache config:
ScriptAlias /cgi-bin/ /QSYS.LIB/QXMLSERV.LIB/
<Directory /QSYS.LIB/QXMLSERV.LIB/>
AllowOverride None
order allow,deny
allow from all
SetHandler cgi-script
Options +ExecCGI
</Directory>
# QXMLSERV (IBM) can be replaced by XMLSERVICE
(download), ZENDSVR6 (php), POWERRUBY, etc.
© 2017 International Business Machines Corporation
Choosing the Right XMLSERVICE
Choose which XMLSERVICE library you want for iDB2Call, iLibCall set the
XMLSERVICE environment variable before calling Python:
export XMLSERVICE=QXMLSERV
or ...
export XMLSERVICE=XMLSERVICE
or ...
export XMLSERVICE=ZENDSVR6
... and so on
or from within Python:
import os os.environ["XMLSERVICE"] = "QXMLSERV" # ...
5/26/2018
17
© 2017 International Business Machines Corporation
Connecting
# iLibCall example
from itoolkit import *
from itoolkit.lib.ilibcall import *
itransport = iLibCall()
# iRestCall example
from itoolkit import *
from itoolkit.rest.irestcall import *
itransport = iRestCall(url, user, password)
© 2017 International Business Machines Corporation
Connecting
# iDB2Call example
from itoolkit import *
from itoolkit.db2.idb2call import *
itransport = iDB2Call(user, password)
# or
conn = ibm_db.connect(database, user, password)
itransport = iDB2Call(conn)
5/26/2018
18
© 2017 International Business Machines Corporation
Basics
from itoolkit import *
from itoolkit.lib.ilibcall import *
itransport = iLibCall()
itool = iToolKit()
itool.add( ... ) # op1
itool.add( ... ) # op2
itool.call(itransport)
op1 = itool.dict_out('op1')
if 'success' in op1:
print (op1['success'])
else:
print (op1['error'])
© 2017 International Business Machines Corporation
Example: Calling an ILE program from Python
from itoolkit import *
from itoolkit.lib.ilibcall import *
itransport = iLibCall()
itool = iToolKit()
itool.add(iCmd('addlible', 'addlible KADLER'))
itool.add(
iPgm('my_key','MYPGM')
.addParm(iData('inchara','1a','a'))
.addParm(iDS('INDS1')
.addData(iData('dscharb','1a','b'))
.addData(iData('desdec','12p2','3.33'))
)
)
itool.call(itransport)
mypgm_results = itool.dict_out('my_key')
5/26/2018
19
© 2017 International Business Machines Corporation
Calling SQL
itool.add(iSqlQuery('query', "select job_name,
elapsed_cpu_time, elapsed_time from
table(qsys2.active_job_info()) x where subsystem =
'QHTTPSVR' fetch first 3 rows only"))
itool.add(iSqlFetch('fetch'))
itool.add(iSqlFree('free')) #more important now
itool.call(tran)
for row in itool.dict_out('fetch')['row']:
print(row)
time.sleep(1)
itool.call(tran)
for row in itool.dict_out('fetch')['row']:
print(row)
© 2017 International Business Machines Corporation
remote ssh
Use option -t to send commands over SSH and log off when done.
Possibilities:
• Use with Jenkins for continuous integration and deployment
• Use with borgi to call programs
• Use db2util to obtain data from DB2
5/26/2018
20
ublu
krengel.tech/ublu - Git repo
Interpretive language for remote systems
programming of IBM i hosts from a Java platform
such as Linux, Mac, OpenBSD or Windows.
as400 -to @mysys -usessl MYSYS.COM MYPROFID myPassWord
commandcall -as400 @mysys ${ WRKSYSSTS OUTPUT(*PRINT) }$
spoolflist -as400 @mysys -to @l MYPROFID
FOR @i in @l $[
@i -to ~ -get name
~ -to ~ -eq QPDSPSTS
IF ~ THEN $[
@i -fetch BREAK
]$
]$
Example Script:
© 2017 International Business Machines Corporation
Toolkits - future
• Open source project underway to re-engineer XMLService
– bitbucket.org/litmis/db2sock
• Why?
– XML → → JSON
– Performance improvements
– Common driver for both DB2 connector and itoolkit classes
• What does it mean for you?
– If you want to stay
o nothing, no plans to deprecate current tech
– If you want to be bleeding-edge
o Perhaps nothing (toolkits may be dynamic)
o Perhaps an alternative toolkit
o May vary by language
5/26/2018
21
© 2017 International Business Machines Corporation
DB2 Connect Offerings
• The IBM DB2 teams have created database adapters for IBM DB2
Universal Database for many open source languages.
• This allows you to connect to IBM i remotely. When connecting remotely, it
requires IBM DB2 Connect
– Contact IBM for pricing
• PHP IBM-DB2
– php.net/manual/en/book.ibm-db2.php
• Python ibm_db
– github.com/ibmdb/python-ibmdb
• Ruby ibm_db
– github.com/ibmdb/ruby-ibmdb
• Node.js
– github.com/ibmdb/node-ibm_db
© 2017 International Business Machines Corporation
JTOpen (IBM Toolbox for Java)
• Longstanding set of Java API's for accessing IBM i
• You're likely already using (i.e. SquirrelSQL, from RDi, etc)
• jt400.sourceforge.net
AS400 as400 = new AS400(this.sys, 'AARON', 'T3E56');
QSYSObjectPathName obj =
new QSYSObjectPathName('MYLIB', 'MYDTAQ, "DTAQ").getPath();
KeyedDataQueue dq = new KeyedDataQueue(as400, obj);
while (true) {
KeyedDataQueueEntry DQData = dq.read("INPUT", this.wait, "EQ");
processEntry(dq, DQData);
}
5/26/2018
22
© 2017 International Business Machines Corporation
Node.js jdbc package
• Node.js JDBC package
– npmjs.com/package/jdbc
– utilizes a single JVM per OS instance (vs. one per process) that proxies
requests.
• Article on using to connect to IBM i from Linux
– krengel.tech/mcpress-nodejs-jdbc
// Select statement example.
conn.createStatement(function(err, statement) {
statement.executeQuery("SELECT * FROM blah;", function(err, resultset) {
resultset.toObjArray(function(err, results) {
callback(null, resultset);
});
});
});
© 2017 International Business Machines Corporation
• Designed to specialize in the IBM i JDBC driver (included as part of JTOpen)
– npmjs.com/package/node-jt400
const pool =
require('node-jt400').pool({
host: 'myhost', user: 'myuser', password: 'xxx'
});
pool.query(
'SELECT FIELD1, FIELD2 FROM FOO WHERE BAR=? AND BAZ=?', [1, 'a']
).then(function (result) {
const field1 = result[0].FIELD1;
...
});
Node.js node-jt400 package
5/26/2018
23
© 2017 International Business Machines Corporation
ODBC
• IBM i Access for Windows provides an ODBC driver for:
– Windows
– Linux
– ….. And coming soon……………
• Leverage this from any language that supports ODBC connections
(usually a community module)
• Why is this better than JDBC?
– Maintenance
– Performance
– Simplicity
© 2017 International Business Machines Corporation
ODBC in Python REPL
5/26/2018
24
© 2017 International Business Machines Corporation
Simplified form of previous screen
© 2017 International Business Machines Corporation
ODBC
• IBM i Access for Windows provides an ODBC driver for:
– Windows
– Linux
– IBM i
– Mac. NOT! Priority = 4 Billionth :-|
• An ODBC driver so that IBM i can talk to itself? Nonsense!!
• Why would this be important???
5/26/2018
25
© 2017 International Business Machines Corporation
DB2 Storage Engines for MySQL and MariaDB
• Supporting open source applications
while simplifying data management
– Applications written to MySQL or MariaDB,
but data stored in DB2
– One database to manage, backup
and protect
– Provides access to MySQL or MariaDB
data from RPG, DB2 Web Query and more
• Combination of Apache, PHP and Open Source Database like MySQL
enables 1000s of applications on i
– Customer Relationship Management,
E-Commerce, Portals and Wikis
PHP
Application
MySQL/MariaDB
DB2 for i
Writes to
Data stored in
Accesses
Data
RPG
Application
© 2017 International Business Machines Corporation
Roll-your-own web services –the concept
• Expose web services (likely REST) in any language you choose.
• Consume those web services in any language you choose
– Consumption of web services is often OSS for modernization
5/26/2018
26
Node.js approach
$ yum install nodejs
$ npm install express
$ node app.js
expressjs.com - Home page
krengel.tech/ibmioss-rpms - Yum install
--- app.js ---var express = require('express')var app = express()
app.get('/', function (req, res) {res.send({data: 'value'})
})
app.listen(8001)
© 2017 International Business Machines Corporation
Swagger is the key to integration
• A Swagger document is the REST API equivalent of a WSDL document
for a SOAP-based web service
– Specifies the list of resources that are available in the REST API and
the operations that can be called on those resources
– Specifies the list of parameters to an operation, including the name
and type of the parameters
• Allows IBM i RESTful APIs to be exposed in various platforms, such as
IBM Cloud Platform and IBM API Connect
52
5/26/2018
27
© 2017 International Business Machines Corporation
53
Node.js Web Service
APIMappingModel
iToolKit
Swagger Doc
Describes the API
DELETE
POST
PUT
GET
REST API
IBM i
RPG *PGM COBOL *PGM
DB2 for i DB2 for i
IBM Cloud can use Swagger doc to integrate with API
© 2017 International Business Machines Corporation
FLIGHT400 web services example
Repo:
bitbucket.org/litmis/nodejs/src/master/examples/express_api_flight400_node6
5/26/2018
28
© 2017 International Business Machines Corporation
FLIGHT400 web services example
© 2017 International Business Machines Corporation
FLIGHT400 web services example
5/26/2018
29
© 2017 International Business Machines Corporation
FLIGHT400 web services example
// flight 400
var FlightJson400 = require('./flight400/flightjson400').FlightJson400;
var flight400 = new FlightJson400();
// call the packages we need
var express = require('express'); // call express
var app = express(); // define our app using express
var port = process.env.PORT || 47700; // set our port
// ROUTES FOR OUR API
var router = express.Router(); // get an instance of the express Router
© 2017 International Business Machines Corporation
FLIGHT400 web services example
HTTP Request:
// GET:/flight400/api/all/from|to
// http://myibmi/flight400/api/all/from
Sample output:
{
"ok": true,
"status": 200,
"message": "found (f)",
"result":
[
{ "city": "Albany" },
{ "city": "Albuquerque" },
{ "city": "Winnipeg" }
]
}
5/26/2018
30
© 2017 International Business Machines Corporation
FLIGHT400 web services example
router.route('/all/:fromTo')
.get(function(req, res) {
var fromTo = req.params.fromTo.substring(0, 1).toUpperCase();
if (fromTo == 'F') {
flight400.GetFromCities(function(rsp) {
res.statusCode = rsp["status"];
return res.json(rsp);
});
} else {
flight400.GetToCities(function(rsp) {
res.statusCode = rsp["status"];
return res.json(rsp);
});
}
});
© 2017 International Business Machines Corporation
FLIGHT400 web services example
5/26/2018
31
© 2017 International Business Machines Corporation
Data Queues
© 2017 International Business Machines Corporation
Data Queue example
• Data Queues
– Good for general IPC (Inter Process Communication).
– Good for cross-language support.
• Business Application
– Right language? RPG?
• Want to send SMS text messages? Hmmmm….
– Well, there's a Twilio service to send text messages
– Twilio has a REST API
– Node.js has an easy-to-use library built on that API, so…. Node.js!
5/26/2018
32
© 2017 International Business Machines Corporation
Data Queue example
RPG
*DTA
Q
© 2017 International Business Machines Corporation
Data queue example code
var xt = require('./xstoolkit/lib/itoolkit');
var dq = require('./xstoolkit/lib/idataq2');
var twilio = require('twilio');
var accountSid = 'abcdefghijklmn'; // Twilio Account SID
var authToken = 'abcdefghijklmn'; // Twilio Auth Token
var conn = new xt.iConn('*LOCAL', 'AARON', 'ipasswrd');
var dtq = new dq.iDataQueue(conn);
var client = new twilio.RestClient(accountSid, authToken);
var data = '';
5/26/2018
33
© 2017 International Business Machines Corporation
Data queue example code
while (data.body !== '*end') {
data = JSON.parse(
dtq.receiveFromDataQueue('SNDSMSQ', 'MYLIB', 5000, -1)
);
console.log('data: ' + JSON.stringify(data));
sendSMS(data);
}
function sendSMS(data) {
client.messages.create({
body: data.body, // SMS body
to: data.to, // SMS to number
from: data.from // SMS from a valid Twilio number
}, function(err, message) {
if (err) {
console.error(err.message);
}
});
}
© 2017 International Business Machines Corporation
Data queue example code
RPG forms JSON that looks like this:{
"body":"Hello World",
"to":"+123456789",
"from":"+123456789"
}
Sends it like this:
dcl-pr snddtaq extpgm('QSNDDTAQ');
dtqname like(d#dtqname) const;
dtqlib like(d#dtqlib) const;
dtqlength like(d#dtqlength) const;
dtqdata char(32766) const options(*varsize);
end-pr;
5/26/2018
34
© 2017 International Business Machines Corporation
Data queue example code
• Of course, all open source
• (You can use this from your existing RPG, without needing to know
Node.js)
• github.com/RainerRoss/Send-SMS-with-Twilio-from-IBM-i
© 2017 International Business Machines Corporation
My Open Source Blog… ibmsystemsmag.com/Blogs/Open-Your-i
5/26/2018
35
© 2017 International Business Machines Corporation
THANK YOU!!!
© 2017 International Business Machines Corporation
facebook.com/IBMPowerSystems
twitter.com/IBMPowerSystems
linkedin.com/company/ibm-power-systems
IBM Power Systems Official Channels:
youtube.com/c/ibmpowersystems
ibm.com/blogs/systems/topics/servers/power-systems/
Power Systems Social Media
5/26/2018
36
© 2017 International Business Machines Corporation 71
More to Follow:
Blogs Twitter #Hashtags
• IBM Systems Magazine You and i
(Steve Will)
• IBM Systems Magazine i-Can
(Dawn May)
• IBM Systems Magazine: iDevelop
(Jon Paris and Susan Gantner)
• IBM Systems Magazine: iTalk with
Tuohy
• IBM Systems Magazine: Open your i
(Jesse Gorzinski)
• Aaron Bartell Blog
• Steve Pitcher Blog
• Trevor Perry Blog
• IBM DB2 for i (Mike Cain)
• IBM DB2 Web Query for i (Doug Mack)
• Modern-i-zation (Tim Rowe)
@IBMSystems@COMMONug
@IBMChampions@IBMSystemsISVs
@LinuxIBMMag@OpenPOWERorg
@AIXMag@IBMiMag
@ITJungleNews@SAPonIBMi@SiDforIBMi
@IBMAIXeSupp@IBMAIXdoc
#PowerSystems
#IBMi
#IBMAIX
#POWER8
#LinuxonPower
#OpenPOWER
#HANAonPower
#ITinfrastructure
#OpenSource
#HybridCloud
#BigData