Professional Documents
Culture Documents
HelloWorldExample
Search
View EditLogIn
03.HelloWorldExample
02.SpoonIntroduction
PentahoDataIntegration(Kettle)Tutorial
04.RefiningHelloWorld
HelloWorldExample
Althoughthiswillbeasimpleexample,itwillintroduceyoutosomeofthefundamentalsofPDI:
WorkingwiththeSpoontool
Transformations
StepsandHops
Predefinedvariables
PreviewingandExecutingfromSpoon
ExecutingTransformationsfromaterminalwindowwiththePantool.
Overview
Let'ssupposethatyouhaveaCSVfilecontainingalistofpeople,andwanttocreateanXMLfilecontaininggreetingsforeachofthem.
IfthiswerethecontentofyourCSVfile:
last_name,name
Suarez,Maria
Guimaraes,Joao
Rush,Jennifer
Ortiz,Camila
Rodriguez,Carmen
daSilva,Zoe
ThiswouldbetheoutputinyourXMLfile:
<Rows>
<row>
<msg>Hello,Maria!</msg>
</row>
<row>
<msg>Hello,Joao!</msg>
</row>
<row>
<msg>Hello,Jennifer!</msg>
</row>
<row>
<msg>Hello,Camila!</msg>
</row>
<row>
<msg>Hello,Carmen!</msg>
</row>
<row>
<msg>Hello,Zoe!</msg>
</row>
</Rows>
ThecreationofthefilewithgreetingsfromtheflatfilewillbethegoalforyourfirstTransformation.
ATransformationismadeofStepslinkedbyHops.TheseStepsandHopsformpathsthroughwhichdataflows.Thereforeit'ssaidthataTransformationisd a ta fl o w
o ri e n te d .
Preparingtheenvironment
BeforestartingaTransformation,createaTutorialfolderintheinstallationfolderorsomeotherconvenientplace.Thereyou'llsaveallthefilesforthistutorial.Thencreatea
CSVfileliketheoneshownabove,andsaveitintheTutorialfolderaslist.csv.
Transformationwalkthrough
Theproposedtaskwillbeaccomplishedinthreesubtasks:
1. CreatingtheTransformation
2. ConstructingtheskeletonoftheTransformationusingStepsandHops
3. ConfiguringtheStepsinordertospecifytheirbehavior
CreatingtheTransformation
1. ClickNew,thenselectTransformation.AlternativelyyoucangototheFilemenu,thenselectNew,thenTransformation.YoucanalsojustpressCtrlN.
2. IntheViewnavigator,clickTransformation1,thenclickSettings.OrrightclickthediagramandclickTransformationSettings.OrusetheCtrl+Tshortcut.
3. AwindowappearswhereyoucanspecifyTransformationproperties.Inthiscase,justwriteanameandadescription,thenclickSave.
4. SavetheTransformationintheTutorialfolderwiththenamehello.Thiswillcreateahello.ktrfile.
ConstructingtheskeletonoftheTransformationusingStepsandHops
ASte p istheminimalunitinsideaTransformation.AwidevarietyofStepsareavailable,groupedintocategorieslikeInputandOutput,amongothers.EachStepisdesigned
toaccomplishaspecificfunction,suchasreadingaparameterornormalizingadataset.
AH o p isagraphicalrepresentationofdataflowingbetweentwoSteps,withanoriginandadestination.ThedatathatflowsthroughthatHopconstitutestheOu tp u tD a ta of
theoriginStep,andtheIn p u tD a ta ofthedestinationStep.AHophasonlyoneoriginandonedestination,butmorethanoneHopcouldleaveaStep.Whenthathappens,
theOutputDatacanbecopiedordistributedtoeverydestination.Likewise,morethanoneHopcanreachaStep.Inthoseinstances,theStephastohavetheabilitytomerge
theInputfromthedifferentStepsinordertocreatetheOutput.
ATransformationhastodothefollowing:
ReadtheCSVfile
Buildthegreetings
SavethegreetingsintheXMLfile
Foreachoftheseitemsyou'lluseadifferentStep,accordingtothenextdiagram:
Inthisexample,thecorrespondencebetweentasksandStepsisonetoonebecausetheTransformationisverysimple.Itisn'talwaysthatway,though.
Here'showtostarttheTransformation:
1. TotheleftoftheworkspaceistheStepsPalette.SelecttheInputcategory.
2. DragtheCSVfileontotheworkspaceontheright.
3. SelecttheScriptingcategory.
4. DragtheModifiedJavaScriptValueicontotheworkspace.
5. SelecttheOutputcategory.
6. DragtheXMLOutputicontotheworkspace.
NowyouwilllinktheCSVfileinputwiththeModifiedJavaScriptValuebycreatingaHop:
1. SelectthefirstStep.
2. HoldtheShiftkeyanddragtheiconontothesecondStep.
3. LinktheModifiedJavaScriptValuewiththeXMLOutputviathissameprocess.
SpecifyingStepbehavior
EveryStephasaconfigurationwindow.ThesewindowsvaryaccordingtothefunctionalityoftheStepsandthecategorytowhichtheybelong.However,Ste p N a me is
alwaysarepresentativenameinsidetheTransformationthisdoesn'tchangeamongStepconfigurations.Ste p D e scri p ti o n allowsyoutoclarifythepurposeoftheStep.
ConfiguringtheCSVfileinputStep
1. DoubleclickontheCSVfileinputStep.
2. TheconfigurationwindowbelongingtothiskindofStepwillappear.Hereyou'llindicatethelocation,formatandcontentoftheinputfile.
3. ReplacethedefaultnamewithonethatismorerepresentativeofthisStep'sfunction.Inthiscase,typeinnamelist.
4. IntheFilenamefield,typethenameandlocationoftheinputfile.
N ote :Justtotherightofthetextboxisasymbolwithareddollarsign.Thismeansthatyoucanusevariablesaswellasplaintextinthatfield.Avariablecanbe
writtenmanuallyas${name_of_the_variable}orselectedfromthevariablewindow,whichyoucanaccessbypressingCtrlSpacebar.Thiswindowshowsboth
predefinedanduserdefinedvariables,butsinceyouhaven'tcreatedanyvariablesyet,rightnowyou'llonlyseethepredefinedones.Amongthose,select:
${Internal.Transformation.Filename.Directory}
Nextthenameofthevariable,typeaslashandthenameofthefileyoucreated:
${Internal.Transformation.Filename.Directory}/list.csv
Atruntimethevariablewillbereplacedbyitsvalue,whichwillbethepathwheretheTransformationwassaved.TheTransformationwillsearchthefile
list.csvinthatlocation.
5. ClickGetFieldstoaddthelistofcolumnnamesoftheinputfiletothegrid.Bydefault,theStepassumesthatthefilehasheaders(theHeaderrowpresentcheckboxis
checked).
N ote :TheGetFieldsbuttonispresentinmostSteps'configurationwindows.ItspurposeistoloadagridwithdatafromexternalsourcesorpreviousSteps.Even
whenthefieldscanbewrittenmanually,thisbuttongivesyouashortcutwhentherearemanyavailablefieldsandyouwanttousealloralmostallofthem.
6. Thegridhasnowthenamesofthecolumnsofyourfile:last_nameandname,andshouldlooklikethis:
ConfiguringtheModifiedJavaScriptValueStep
1. DoubleclickontheModifiedJavaScriptValueStep.
2. TheStepconfigurationwindowwillappear.ThisisdifferentfromthepreviousStepconfigwindowinthatitallowsyoutowriteJavaScriptcode.Youwilluseittobuildthe
message"Hello,"concatenatedwitheachofthenames.
3. NamethisStepGreetings.
4. Themainareaoftheconfigurationwindowisforcoding.Totheleft,thereisatreewithasetofavailablefunctionsthatyoucanuseinthecode.Inparticular,thelasttwo
brancheshavetheinputandoutputfields,readytouseinthecode.Inthisexampletherearetwofields:last_nameandname.Writethefollowingcode:
varmsg='Hello,'+name.getString()+"!"
N ote :Thetextname.getString()canbewrittenmanually,orbydoubleclickingonthetextinthefunctiontree.
5. Atthebottomyoucantypeanyvariablecreatedinthecode.Inthiscase,youhavecreatedavariablenamedmsg.Sinceyouneedtosendthismessagetotheoutput
file,youhavetowritethevariablenameinthegrid.Thisshouldbetheresult:
Wa r ning:Don'tmixthesevariableswithPDIvariablestheyarenotthesame.
N ote :ModifiedisnotanadjectiveforJavaScript,butfortheStep.YouarenotdealingwithavariantofJavaScriptitistheStepitselfthatismodified.Itisan
enhancedversionoftheoriginalStep,whichyoufoundinpreviousversionsofPDI.
6. ClickOKtofinishconfiguringStepModifiedScriptValue.
7. SelecttheStepyoujustconfigured.InordertocheckthatthenewfieldwillleavethisStep,youwillnowseetheInputandOutputFields.In p u tFi e l d sarethedata
columnsthatreachaStep.Ou tp u tFi e l d sarethedatacolumnsthatleaveaStep.ThereareStepsthatsimplytransformtheinputdata.Inthiscase,theinputandoutput
fieldsareusuallythesame.ThereareSteps,however,thataddfieldstotheOutputCalculator,forexample.ThereareotherStepsthatfilterorcombinedatacausing
thattheOutputhaslessfieldsthattheInputGroupby,forexample.
8. RightclicktheSteptobringupacontextmenu.
9. SelectShowInputFields.You'llseethattheInputFieldsarelast_nameandname,whichcomefromtheCSVfileinputStep.
10. SelectShowOutputFields.You'llseethatnotonlydoyouhavetheexistingfields,butalsothenewmsgfield.
ConfiguringtheXMLOutputStep
1. DoubleclicktheXMLOutputStep.TheconfigurationwindowforthiskindofStepwillappear.Hereyou'regoingtosetthenameandlocationoftheoutputfile,and
establishwhichofthefieldsyouwanttoinclude.YoumayincludeallorsomeofthefieldsthatreachtheStep.
2. NametheStepFilewithGreetings.
3. IntheFileboxwrite:
${Internal.Transformation.Filename.Directory}/Hello.xml
4. ClickGetFieldstofillthegridwiththethreeinputfields.Intheoutputfileyouonlywanttoincludethemessage,sodeletenameandlast_name.
5. SavetheTransformationagain.
Howdoesitwork?
WhenyouexecuteaTransformation,almostallStepsareexecutedsimultaneously.TheTransformationexecutesasynchronouslytherowsofdataflowthroughthe
Stepsattheirownpace.EachprocessedrowflowstothenextStepwithoutwaitingfortheothers.InrealworldTransformations,forgettingthischaracteristiccanbea
significantsourceofunexpectedresults.
Atthispoint,HelloWorldisalmostcompletelyconfigured.ATransformationreadstheinputfile,thencreatesmessagesforeachrowviatheJavaScriptcode,andthenthe
messageissenttotheoutputfile.Thisisasmallexamplewithveryfewrowsofnames,soitisdifficulttonoticetheasynchronousexecutioninaction.Keepinmind,however,
thatit'spossiblethatatthesametimeanameisbeingwrittenintheoutputfile,anotherisleavingthefirstStepoftheTransformation.
Verify,previewandexecute
1. BeforeexecutingtheTransformation,checkthateverythingisproperlyconfiguredbyclickingVerify.SpoonwillverifythattheTransformationissyntacticallycorrect,and
lookforunreachableStepsandnonexistentconnections.Ifeverythingisinorder(itshouldbeifyoufollowedtheinstructions),youarereadytopreviewtheoutput.
2. SelecttheJavaScriptStepandthenclickPreviewbutton.Thefollowingwindowwillappear:
3. Asyoucansee,SpoonsuggeststhatyoupreviewtheselectedStep.ClickQuickLaunch.Afterthat,youwillseeawindowwithasampleoftheoutputoftheJavaScript
Step.Iftheoutputiswhatyouexpected,you'rereadytoexecutetheTransformation.
4. ClickRun.
5. Spoonwillshowawindowwhereyoucanset,amongotherinformation,theparametersfortheexecutionandthelogginglevel.ClickLaunch.
6. AnewwindowtabwillappearintheJobwindow.Thisisthelogtab,whichcontainsalogofthecurrentexecution.
Thelogtabhastwosections:Anupperpartandalowerpart.
IntheuppersideyoucanseetheexecutedoperationsforeachStepoftheTransformation.Inparticular,payattentiontothese:
Read:thenumberofrowscomingfrompreviousSteps.
Written:thenumberofrowsleavingfromthisSteptowardthenext.
Input:thenumberofrowsreadfromafileortable.
Output:thenumberofrowswrittentoafileortable.
Errors:errorsintheexecution.Ifthereareerrors,thewholerowwillbecomered.
Inthelowerportionofthewindow,youwillseetheexecutionstepbystep.Thedetailwilldependontheloglevelestablished.Ifyoupayattentiontothisdetail,youwillseethe
asynchronicityoftheexecution.Thelastlineofthetextwillbe:
SpoonThetransformationhasfinished!!
Ifthereweren'terrormessagesinthetext,openthenewlygeneratedHello.xmlfileandcheckitscontent.
Pan
PanallowsyoutoexecuteTransformationsfromaterminalwindow.Thescriptispan.batonWindows,orpan.shonotherplatforms,andit'slocatedintheinstallationfolder.If
yourunthescriptwithoutanyoptions,you'llseeadescriptionpanwithalistofavailableoptions.
ToexecuteyourTransformation,trythesimplestcommand:
Pan/file<Jobs_path>/Hello.ktr/norep
/norepisacommandtoaskSpoonnottoconnecttotherepository.
/fileprecedesthenameofthefilethatcontainstheTransformation.
<Jobs_path>isthefullpathtotheTutorialfolder,forexample:
C:/Pentaho/Tutorial
or
/home/PentahoUser/Tutorial
Theotheroptionsarerunwithdefaultvalues.
Afteryouenterthiscommand,theTransformationwillbeexecutedinthesamewayitdidinsideSpoon.Inthiscase,thelogwillbewrittentotheterminalunlessyouspecifya
filetowriteto.Theformatofthelogtextwillvaryalittle,buttheinformationwillbebasicallythesamethatyousawinthegraphicalenvironment.
02.SpoonIntroduction
PentahoDataIntegration(Kettle)Tutorial
04.RefiningHelloWorld
Comments(12)
HideComments CollapseAll
Anonymoussays:
Jul29,2008
Whenfollowingthistutorial,IgetthefollowingerrorswhendoingVerifyafterhookingeverythingup:
[4Error]ModifiedJavaScriptValue
Couldn'taddInputfieldstoScript!Error:
java.lang.RuntimeException:Unabletoverifyif[last_nameString(9)<binarystring>]isnullornotbecauseofanerror:java.lang.ClassCastException:
java.lang.Stringcannotbecastto[B
[4Error]ModifiedJavaScriptValue
Generalerrorexecutingscript:
org.mozilla.javascript.EcmaError:ReferenceError:"name"isnotdefined.(script#3)
IfIrunthetransformation,however,itworksasexpected.I'musingpdiopen3.0.4GA
Anonymoussays:
Jul29,2008
Iwasalsogettingexactlythesameerrorspostedafterfollowingthetutorialbuteverythingworkedrightwhenexecutingthetransformation.IhaveKettle
3.0.3.GA0569installed.
Anonymoussays:
Aug03,2008
Hiya,samehere,Imean,gettingerrorasstatedabovebutthetransformationrunsfineandoutputgotasexpected...
thanksforthewonderfulworkofcreatingthistutorial.
MariaCarinaRoldansays:
Aug04,2008
Ithinkthatit'sabugrelatedwiththe"csvinputstep".Either:
1.Replacethatstepwitha"textfileinput"
or
2.Switchlazyconversionoffincsvinput(thankstosbodenforthistip)
andyoushouldbeOK.
Thanksforthe"wonderfulwork"part
mc
Anonymoussays:
Sep11,2008
Thanksforyougoodwork!
Ifacethesameerror,butwhenIturnoffthecompatibilitymode,that'sright
FrankMilbonasays:
Jun16,2009
Thankyouverymuchforthistutorial.Itisstillveryhelpfulalthoughtheuserinterfacehasalreadychangedquiteabit.
Yousaidthatthestepsofatransformationrunconcurrently.Iwonderifthisisalsotrueforthestepsofajob.Willtheyalsorunconcurrentlyorwillthenextstep
inajobonlyexecuteafterthepreviousonehascompleted?
...Sorry,theanswerisonthenextpage.Jobentriesareexecutedinsequence.
KennethFreidanksays:
Feb13,2012
(v4.2.1)COMMENTSTRANSFORMATIONWALKTHROUGH
CreatingtheTransformation
Closethewelcomescreenbeforestep1.
Rightclick"Transformation1"togetto'Settings',orleftclickselect"Transformation1"andclick"Edit/Settings"fromthemenu.
Afterclosingthesettingswindow,thetreelayoutonthelefthandofthescreenneedstoberefreshedbeforethenewnameappearsinplaceof
"Transformation1".Youcanrefreshthetreebyclickingonthe"Design"tab,thenclickingbackonthe"View"tab.Aftersavingthetransfroamtion,thetab
ontherighthandsideofthescreenrefreshesfromtheoldname,"Transformation1",theyournewname.
ConstructiontheSkeleton....
Here'showtostartthetransform....
Clickthe"Design"tabonthelefttogettothepallette.
Afterdraggingthe"csv"totheright,collapsethe"Input"categorythatyouselectedontheleft,thenyoucanseethe"Scripting"category.Collapse
eachcategroyafteritsuse,soyoucanseetheothercategories.Repeatedclicksonthetriangleicontotheleftofthecategorycollapsesand
expandsthecategory.
Afterdraggingthe"csvfileinput"stepontopofthe"ModifiedJavaScriptValue"step,abluearrowappearedrepresentingthehop,andapopup
menuappeared.IfIdidnotleftclickthe"Mainoutputofstep"inthepopupmenu,thehopdidnotstay,butwasdeleted.So,makesureyouclick
the"Mainoutputofstep".Thebluearrowchangestoblackwhenthehopisaccepted.
ConfiguringtheCSVfile...
Uncheckthe"lazyconversion"checkbox,asothershaveposted.Don'tknowwhatthisdoes,butitremovesanerrormessageyougetlateron.
ConfiguringtheModifiedJavascript...
Clickthe"Compatibilitymode"checkbox,astheotherpostershavepointedout,sothatyouwillseethe".getString()"partshowupintheInput
fieldslist.
ConfiguringtheXMLoutput...
Thereisaseparatetextboxthatholdsthefileextension.Thisextensionisappendedtothefilename.Thereisahandy"showfilename"button
thatyoucanusetocheckifyou'vegotthefullpathandcorrectfilenamethatwillactuallybeused.
Step4saystoclick"GetFields".Clickthe"Fields"tabatthetopofthewindowbefore"Getfields".
Todeletethenameandlast_name,Ifirstclickedthenumberofthefieldontheleftofthegrid.Thisselectedtheentirerow.
Verify,Preview,....
"Verify"isunderthe"Action"menuitem.Thereisalsoa"verify"iconatthetopoftheworkspace,justunderthenameofthetransformwhichshows
asthetaboftheworkspace.Theverifyiconlookslikeasheetoofpaperwithagreencheckmark.
Ifyouforgottouncheckthe"lazyconversion"checkboxinthe"CSVFileSettings",youwillgetanerrorwhenverifying.
The"TransformDebug"dialogboxdoesnotshowthepreviewoptionsuntilyouclickoneofthestepsontheleftofthedialogbox.
Theresultsoftherunaredisplayedinanewwindowthatopensbelowtheworkspacecalled"ExecutionResults".Thelogisatabinthenew
window.ThelettersI,O,R,W,U,andEareabreviationsfortherecordedstatsINPUT,OUTPUT,READ,WRITTEN,ERRORS.Idon'tknowwhatU
means.
BrianWusays:
Jun29,2012
@Kenneththanksforthe4.2.1updateveryyyhelpfulandwishIsawitbeforeIhadgonethroughitmyself).
Whenverifying,Igeta"Filespecificationsarenotchecked."Itriedtofigureoutwhattheproblemwasforawhile,butthetransformationendeduprunning
withouterrors,soI'vestoppedlookingintoit.
DavidLopezsays:
Jul11,2013
@Kenneth
Thankssomuchforthecomment.
RightnowIamworkingwithKettleSpoon4.4.1GAand,concerningtheExecutionstep,theExecutionResultswindowdisplayedbelowholdsfourtabs:
Exe cu ti o n H i sto ryL o g g i n g Ste p Me tri csPe rfo rma n ce Gra p h
TheonethatcontainsINPUT,OUTPUT,READ,WRITTEN,ERRORSisSte p Me tri cs,whichdisplaysallthesedataregardingeachstepeverythingis
displayedinagrid,whereeachrowisaStepandeachcolumnoneoftheseattributes,Bytheway,UisUPDATED:)
RandySinuratsays:
Dec20,2013
Everytimeisettheoutputxmlstep,ialwaysgetthiserror:
"Noenumconstclassorg.pentaho.di.trans.steps.xmloutput.XMLField$ContentType."
Afterthat,icannotopenthestepconfigurationwindow.
Iamusingkettleversion5.0.1.
Whatactuallyhappened???Iamnewbie,bytheway.
Thankyou.
NOTE:
Ialreadyknowtheproblem.It'sthekettleversion.
Kettle5.0.1won'tdotheoutputworkonme.Ithinkitisnotstableyet.CMIIW.
Thankyou.
MarvinHorstsays:
Dec20,2013
Randy
IjustfinishedthehelloworldtutorialandIalsogotthiserror.TheproblemwasthatIdidn'thaveaContentTypedefinedinthefieldstaboftheXMLoutput
command.AfterdefiningaContenttypetheerrorwentaway
RandySinuratsays:
Dec30,2013
DearMarvin,
Itriedyouradvice,andit'sworked.
Idefinedthecontenttype.Ichoseelement.
Whatidon'tknowisthedifferencebetweenelementandattributecontenttype.
Thankyou.
"ThisdocumentationismaintainedbythePentahocommunity,andmembersareencouragedtocreatenewpagesintheappropriatespaces,oreditexistingpagesthatneed
tobecorrectedorupdated."
"PleasedonotleavecommentsonWikipagesaskingforhelp.Theywillbedeleted.Usetheforumsinstead."
PentahoDataIntegration
BrowseSpace
AddContent
LatestPentahoDataIntegration(akaKettle)Documentation
YourAccount
Anonymous
AguidetosettingupPDIinaMicrosoftclientserverstyleenvironment
Pages
BlackBoxTesting
Labels
History
CarteUserDocumentation
Attachments
LogIn
ClusteringwithPentahoDataIntegration
News
SignUp
Exportingresources
Advanced
Featurecheckboxes
FrequentlyAskedQuestions
GettingStarted
KitchenUserDocumentation
Launchingjobentriesinparallel
ListofAvailablePentahoDataIntegrationPlugIns
Mytransformationisrunningslow,whatdoIdo?!
NamedParameters
PanUserDocumentation
PDIDeveloperinformation
PentahoDataIntegration(Kettle)Tutorial
01.InstallingKettle
02.SpoonIntroduction
03.HelloWorldExample
04.RefiningHelloWorld
PentahoDataIntegration3.0migrationguide
PentahoDataIntegrationCaseStudies
NotationGuide
PentahoDataIntegrationJavaAPIExamples
PentahoDataIntegrationJobEntries
PentahoDataIntegrationScreenshots
PentahoDataIntegrationRecordedDemos
PentahoDataIntegrationv3.2.JobEntries
Slaveserversandclustering
Specialdatabaseissuesandexperiences
SpoonUserGuide
Stepperformancemonitoring
What'snewinPDIversion3.1
What'snewinPDIversion3.2
SpecialOperatingSystemissuesandexperiences
WritingyourownPentahoDataIntegrationPlugIn
DocumentingPentahoDataIntegration(Kettle)Projects
Kettledependencymanagement
KettleExchange
OSGIenabledKettle
MonitoringSWTGraphicsResourceswithSleak
DataQualityIntegrationHome
PartitioningdatawithPDI
ImportUserDocumentation
Configuringlogtablesforconcurrentaccess
PentahoDataIntegration(akaKettle)Concepts,BestPracticesand
Solutions
PigScriptExecutor
Marketplace
TheThinKettleJDBCdriver
Databasetransactionsinjobsandtransformations
Jobcheckpointsandrestartability
CarteConfiguration
AddingIvySupportandProjectRestructure
ColumnFormat
MongoDBOutputIC
NuoDB
DocumentationTemplateforStepsandJobEntries
MongoDBInputIC
test
Services_Yarn_Documentation
AlfrescoOutputPluginforKettle
PentahoDataIntegrationSteps
What'snewinPDI4.0
MongoDBInputStep(Draft_5_3)
OSGIinKettle
AdaptavistThemeBuilder(4.2.0)PoweredbyAtlassianConfluence3.3.3,theEnterpriseWiki