/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.
*
******************************************************************************/
package org.pentaho.di.trans.steps.webservices;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.pentaho.di.core.CheckResultInterface;
import org.pentaho.di.core.KettleClientEnvironment;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.row.value.ValueMetaString;
import org.pentaho.di.core.variables.Variables;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.repository.StringObjectId;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.utils.TestUtils;
import org.pentaho.metastore.api.IMetaStore;
import org.w3c.dom.Node;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class WebServiceMetaTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
if ( !KettleClientEnvironment.isInitialized() ) {
KettleClientEnvironment.init();
}
}
@Test
public void testLoadXml() throws Exception {
Node node = getTestNode();
DatabaseMeta dbMeta = mock( DatabaseMeta.class );
IMetaStore metastore = mock( IMetaStore.class );
WebServiceMeta webServiceMeta = new WebServiceMeta( node, Collections.singletonList( dbMeta ), metastore );
assertEquals( "httpUser", webServiceMeta.getHttpLogin() );
assertEquals( "tryandguess", webServiceMeta.getHttpPassword() );
assertEquals( "http://webservices.gama-system.com/exchangerates.asmx?WSDL", webServiceMeta.getUrl() );
assertEquals( "GetCurrentExchangeRate", webServiceMeta.getOperationName() );
assertEquals( "opRequestName", webServiceMeta.getOperationRequestName() );
assertEquals( "GetCurrentExchangeRateResult", webServiceMeta.getOutFieldArgumentName() );
assertEquals( "aProxy", webServiceMeta.getProxyHost() );
assertEquals( "4444", webServiceMeta.getProxyPort() );
assertEquals( 1, webServiceMeta.getCallStep() );
assertFalse( webServiceMeta.isPassingInputData() );
assertTrue( webServiceMeta.isCompatible() );
assertFalse( webServiceMeta.isReturningReplyAsString() );
List<WebServiceField> fieldsIn = webServiceMeta.getFieldsIn();
assertEquals( 3, fieldsIn.size() );
assertWebServiceField( fieldsIn.get( 0 ), "Bank", "strBank", "string", 2 );
assertWebServiceField( fieldsIn.get( 1 ), "ToCurrency", "strCurrency", "string", 2 );
assertWebServiceField( fieldsIn.get( 2 ), "Rank", "intRank", "int", 5 );
List<WebServiceField> fieldsOut = webServiceMeta.getFieldsOut();
assertEquals( 1, fieldsOut.size() );
assertWebServiceField(
fieldsOut.get( 0 ), "GetCurrentExchangeRateResult", "GetCurrentExchangeRateResult", "decimal", 6 );
WebServiceMeta clone = webServiceMeta.clone();
assertNotSame( clone, webServiceMeta );
assertEquals( clone.getXML(), webServiceMeta.getXML() );
}
void assertWebServiceField( WebServiceField webServiceField, String name, String wsName, String xsdType, int type ) {
assertEquals( name, webServiceField.getName() );
assertEquals( wsName, webServiceField.getWsName() );
assertEquals( xsdType, webServiceField.getXsdType() );
assertEquals( type, webServiceField.getType() );
}
@Test
public void testReadRep() throws Exception {
Repository rep = mock( Repository.class );
IMetaStore metastore = mock( IMetaStore.class );
DatabaseMeta dbMeta = mock( DatabaseMeta.class );
StringObjectId id_step = new StringObjectId( "oid" );
when( rep.getStepAttributeString( id_step, "wsOperation" ) ).thenReturn( "GetCurrentExchangeRate" );
when( rep.getStepAttributeString( id_step, "wsOperationRequest" ) ).thenReturn( "opRequest" );
when( rep.getStepAttributeString( id_step, "wsOperationNamespace" ) ).thenReturn( "opNamespace" );
when( rep.getStepAttributeString( id_step, "wsInFieldContainer" ) ).thenReturn( "ifc" );
when( rep.getStepAttributeString( id_step, "wsInFieldArgument" ) ).thenReturn( "ifa" );
when( rep.getStepAttributeString( id_step, "wsOutFieldContainer" ) ).thenReturn( "ofc" );
when( rep.getStepAttributeString( id_step, "wsOutFieldArgument" ) ).thenReturn( "ofa" );
when( rep.getStepAttributeString( id_step, "proxyHost" ) ).thenReturn( "phost" );
when( rep.getStepAttributeString( id_step, "proxyPort" ) ).thenReturn( "1234" );
when( rep.getStepAttributeString( id_step, "httpLogin" ) ).thenReturn( "user" );
when( rep.getStepAttributeString( id_step, "httpPassword" ) ).thenReturn( "password" );
when( rep.getStepAttributeInteger( id_step, "callStep" ) ).thenReturn( 2L );
when( rep.getStepAttributeBoolean( id_step, "passingInputData" ) ).thenReturn( true );
when( rep.getStepAttributeBoolean( id_step, 0, "compatible", true ) ).thenReturn( false );
when( rep.getStepAttributeString( id_step, "repeating_element" ) ).thenReturn( "repeat" );
when( rep.getStepAttributeBoolean( id_step, 0, "reply_as_string" ) ).thenReturn( true );
when( rep.countNrStepAttributes( id_step, "fieldIn_ws_name" ) ) .thenReturn( 2 );
when( rep.getStepAttributeString( id_step, 0, "fieldIn_name" ) ).thenReturn( "bank" );
when( rep.getStepAttributeString( id_step, 0, "fieldIn_ws_name" ) ).thenReturn( "inBank" );
when( rep.getStepAttributeString( id_step, 0, "fieldIn_xsd_type" ) ).thenReturn( "string" );
when( rep.getStepAttributeString( id_step, 1, "fieldIn_name" ) ).thenReturn( "branch" );
when( rep.getStepAttributeString( id_step, 1, "fieldIn_ws_name" ) ).thenReturn( "inBranch" );
when( rep.getStepAttributeString( id_step, 1, "fieldIn_xsd_type" ) ).thenReturn( "string" );
when( rep.countNrStepAttributes( id_step, "fieldOut_ws_name" ) ) .thenReturn( 2 );
when( rep.getStepAttributeString( id_step, 0, "fieldOut_name" ) ).thenReturn( "balance" );
when( rep.getStepAttributeString( id_step, 0, "fieldOut_ws_name" ) ).thenReturn( "outBalance" );
when( rep.getStepAttributeString( id_step, 0, "fieldOut_xsd_type" ) ).thenReturn( "int" );
when( rep.getStepAttributeString( id_step, 1, "fieldOut_name" ) ).thenReturn( "transactions" );
when( rep.getStepAttributeString( id_step, 1, "fieldOut_ws_name" ) ).thenReturn( "outTransactions" );
when( rep.getStepAttributeString( id_step, 1, "fieldOut_xsd_type" ) ).thenReturn( "int" );
WebServiceMeta webServiceMeta = new WebServiceMeta( rep, metastore, id_step, Collections.singletonList( dbMeta ) );
String expectedXml = ""
+ " <wsURL/>\n"
+ " <wsOperation>GetCurrentExchangeRate</wsOperation>\n"
+ " <wsOperationRequest>opRequest</wsOperationRequest>\n"
+ " <wsOperationNamespace>opNamespace</wsOperationNamespace>\n"
+ " <wsInFieldContainer>ifc</wsInFieldContainer>\n"
+ " <wsInFieldArgument>ifa</wsInFieldArgument>\n"
+ " <wsOutFieldContainer>ofc</wsOutFieldContainer>\n"
+ " <wsOutFieldArgument>ofa</wsOutFieldArgument>\n"
+ " <proxyHost>phost</proxyHost>\n"
+ " <proxyPort>1234</proxyPort>\n"
+ " <httpLogin>user</httpLogin>\n"
+ " <httpPassword>password</httpPassword>\n"
+ " <callStep>2</callStep>\n"
+ " <passingInputData>Y</passingInputData>\n"
+ " <compatible>N</compatible>\n"
+ " <repeating_element>repeat</repeating_element>\n"
+ " <reply_as_string>Y</reply_as_string>\n"
+ " <fieldsIn>\n"
+ " <field>\n"
+ " <name>bank</name>\n"
+ " <wsName>inBank</wsName>\n"
+ " <xsdType>string</xsdType>\n"
+ " </field>\n"
+ " <field>\n"
+ " <name>branch</name>\n"
+ " <wsName>inBranch</wsName>\n"
+ " <xsdType>string</xsdType>\n"
+ " </field>\n"
+ " </fieldsIn>\n"
+ " <fieldsOut>\n"
+ " <field>\n"
+ " <name>balance</name>\n"
+ " <wsName>outBalance</wsName>\n"
+ " <xsdType>int</xsdType>\n"
+ " </field>\n"
+ " <field>\n"
+ " <name>transactions</name>\n"
+ " <wsName>outTransactions</wsName>\n"
+ " <xsdType>int</xsdType>\n"
+ " </field>\n"
+ " </fieldsOut>\n";
String actualXml = TestUtils.toUnixLineSeparators( webServiceMeta.getXML() );
assertEquals( expectedXml, actualXml );
}
@Test
public void testSaveRep() throws Exception {
Node node = getTestNode();
DatabaseMeta dbMeta = mock( DatabaseMeta.class );
IMetaStore metastore = mock( IMetaStore.class );
Repository rep = mock( Repository.class );
WebServiceMeta webServiceMeta = new WebServiceMeta();
webServiceMeta.loadXML( node, Collections.singletonList( dbMeta ), metastore );
StringObjectId aTransId = new StringObjectId( "aTransId" );
StringObjectId aStepId = new StringObjectId( "aStepId" );
webServiceMeta.saveRep( rep, metastore, aTransId, aStepId );
verify( rep ).saveStepAttribute( aTransId, aStepId, "wsUrl", "http://webservices.gama-system.com/exchangerates.asmx?WSDL" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "wsOperation", "GetCurrentExchangeRate" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "wsOperationRequest", "opRequestName" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "wsOperationNamespace", "http://www.gama-system.com/webservices" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "wsInFieldContainer", null );
verify( rep ).saveStepAttribute( aTransId, aStepId, "wsInFieldArgument", null );
verify( rep ).saveStepAttribute( aTransId, aStepId, "wsOutFieldContainer", "GetCurrentExchangeRateResult" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "wsOutFieldArgument", "GetCurrentExchangeRateResult" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "proxyHost", "aProxy" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "proxyPort", "4444" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "httpLogin", "httpUser" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "httpPassword", "tryandguess" );
verify( rep ).saveStepAttribute( aTransId, aStepId, "callStep", 1 );
verify( rep ).saveStepAttribute( aTransId, aStepId, "passingInputData", false );
verify( rep ).saveStepAttribute( aTransId, aStepId, "compatible", true );
verify( rep ).saveStepAttribute( aTransId, aStepId, "repeating_element", null );
verify( rep ).saveStepAttribute( aTransId, aStepId, "reply_as_string", false );
verify( rep ).saveStepAttribute( aTransId, aStepId, 0, "fieldIn_name", "Bank" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 0, "fieldIn_ws_name", "strBank" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 0, "fieldIn_xsd_type", "string" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 1, "fieldIn_name", "ToCurrency" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 1, "fieldIn_ws_name", "strCurrency" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 1, "fieldIn_xsd_type", "string" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 2, "fieldIn_name", "Rank" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 2, "fieldIn_ws_name", "intRank" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 2, "fieldIn_xsd_type", "int" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 0, "fieldOut_name", "GetCurrentExchangeRateResult" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 0, "fieldOut_ws_name", "GetCurrentExchangeRateResult" );
verify( rep ).saveStepAttribute( aTransId, aStepId, 0, "fieldOut_xsd_type", "decimal" );
Mockito.verifyNoMoreInteractions( rep );
}
@Test
public void testGetFields() throws Exception {
WebServiceMeta webServiceMeta = new WebServiceMeta();
webServiceMeta.setDefault();
RowMetaInterface rmi = mock( RowMetaInterface.class );
RowMetaInterface rmi2 = mock( RowMetaInterface.class );
StepMeta nextStep = mock( StepMeta.class );
IMetaStore metastore = mock( IMetaStore.class );
Repository rep = mock( Repository.class );
WebServiceField field1 = new WebServiceField();
field1.setName( "field1" );
field1.setWsName( "field1WS" );
field1.setXsdType( "string" );
WebServiceField field2 = new WebServiceField();
field2.setName( "field2" );
field2.setWsName( "field2WS" );
field2.setXsdType( "string" );
WebServiceField field3 = new WebServiceField();
field3.setName( "field3" );
field3.setWsName( "field3WS" );
field3.setXsdType( "string" );
webServiceMeta.setFieldsOut( Arrays.asList( field1, field2, field3 ) );
webServiceMeta.getFields( rmi, "idk", new RowMetaInterface[]{ rmi2 }, nextStep, new Variables(), rep, metastore );
verify( rmi ).addValueMeta( argThat( matchValueMetaString( "field1" ) ) );
verify( rmi ).addValueMeta( argThat( matchValueMetaString( "field2" ) ) );
verify( rmi ).addValueMeta( argThat( matchValueMetaString( "field3" ) ) );
}
private Matcher<ValueMetaInterface> matchValueMetaString( final String fieldName ) {
return new BaseMatcher<ValueMetaInterface>() {
@Override public boolean matches( Object item ) {
return fieldName.equals( ( (ValueMetaString) item ).getName() );
}
@Override public void describeTo( Description description ) {
}
};
}
@Test
public void testCheck() throws Exception {
WebServiceMeta webServiceMeta = new WebServiceMeta();
TransMeta transMeta = mock( TransMeta.class );
StepMeta stepMeta = mock( StepMeta.class );
RowMetaInterface prev = mock( RowMetaInterface.class );
RowMetaInterface info = mock( RowMetaInterface.class );
Repository rep = mock( Repository.class );
IMetaStore metastore = mock( IMetaStore.class );
String[] input = { "one" };
ArrayList<CheckResultInterface> remarks = new ArrayList<>();
webServiceMeta.check(
remarks, transMeta, stepMeta, null, input, null, info, new Variables(), rep, metastore );
assertEquals( 2, remarks.size() );
assertEquals( "Not receiving any fields from previous steps!", remarks.get( 0 ).getText() );
assertEquals( "Step is receiving info from other steps.", remarks.get( 1 ).getText() );
remarks.clear();
webServiceMeta.setInFieldArgumentName( "ifan" );
when( prev.size() ).thenReturn( 2 );
webServiceMeta.check(
remarks, transMeta, stepMeta, prev, new String[]{}, null, info, new Variables(), rep, metastore );
assertEquals( 2, remarks.size() );
assertEquals( "Step is connected to previous one, receiving 2 fields", remarks.get( 0 ).getText() );
assertEquals( "No input received from other steps!", remarks.get( 1 ).getText() );
}
@Test
public void testGetFieldOut() throws Exception {
DatabaseMeta dbMeta = mock( DatabaseMeta.class );
IMetaStore metastore = mock( IMetaStore.class );
WebServiceMeta webServiceMeta = new WebServiceMeta( getTestNode(), Collections.singletonList( dbMeta ), metastore );
assertNull( webServiceMeta.getFieldOutFromWsName( "", true ) );
assertEquals(
"GetCurrentExchangeRateResult",
webServiceMeta.getFieldOutFromWsName( "GetCurrentExchangeRateResult", false ).getName() );
assertEquals(
"GetCurrentExchangeRateResult",
webServiceMeta.getFieldOutFromWsName( "something:GetCurrentExchangeRateResult", true ).getName() );
}
private Node getTestNode() throws KettleXMLException {
String xml =
" <step>\n"
+ " <name>Web services lookup</name>\n"
+ " <type>WebServiceLookup</type>\n"
+ " <description/>\n"
+ " <distribute>Y</distribute>\n"
+ " <custom_distribution/>\n"
+ " <copies>1</copies>\n"
+ " <partitioning>\n"
+ " <method>none</method>\n"
+ " <schema_name/>\n"
+ " </partitioning>\n"
+ " <wsURL>http://webservices.gama-system.com/exchangerates.asmx?WSDL</wsURL>\n"
+ " <wsOperation>GetCurrentExchangeRate</wsOperation>\n"
+ " <wsOperationRequest>opRequestName</wsOperationRequest>\n"
+ " <wsOperationNamespace>http://www.gama-system.com/"
+ "webservices</wsOperationNamespace>\n"
+ " <wsInFieldContainer/>\n"
+ " <wsInFieldArgument/>\n"
+ " <wsOutFieldContainer>GetCurrentExchangeRateResult</wsOutFieldContainer>\n"
+ " <wsOutFieldArgument>GetCurrentExchangeRateResult</wsOutFieldArgument>\n"
+ " <proxyHost>aProxy</proxyHost>\n"
+ " <proxyPort>4444</proxyPort>\n"
+ " <httpLogin>httpUser</httpLogin>\n"
+ " <httpPassword>tryandguess</httpPassword>\n"
+ " <callStep>1</callStep>\n"
+ " <passingInputData>N</passingInputData>\n"
+ " <compatible>Y</compatible>\n"
+ " <repeating_element/>\n"
+ " <reply_as_string>N</reply_as_string>\n"
+ " <fieldsIn>\n"
+ " <field>\n"
+ " <name>Bank</name>\n"
+ " <wsName>strBank</wsName>\n"
+ " <xsdType>string</xsdType>\n"
+ " </field>\n"
+ " <field>\n"
+ " <name>ToCurrency</name>\n"
+ " <wsName>strCurrency</wsName>\n"
+ " <xsdType>string</xsdType>\n"
+ " </field>\n"
+ " <field>\n"
+ " <name>Rank</name>\n"
+ " <wsName>intRank</wsName>\n"
+ " <xsdType>int</xsdType>\n"
+ " </field>\n"
+ " </fieldsIn>\n"
+ " <fieldsOut>\n"
+ " <field>\n"
+ " <name>GetCurrentExchangeRateResult</name>\n"
+ " <wsName>GetCurrentExchangeRateResult</wsName>\n"
+ " <xsdType>decimal</xsdType>\n"
+ " </field>\n"
+ " </fieldsOut>\n"
+ " <cluster_schema/>\n"
+ " <remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>\n"
+ " <xloc>331</xloc>\n"
+ " <yloc>207</yloc>\n"
+ " <draw>Y</draw>\n"
+ " </GUI>\n"
+ " </step>\n";
return XMLHandler.loadXMLString( xml, "step" );
}
}