001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.jt400;
018    
019    import java.util.ArrayList;
020    import java.util.List;
021    
022    import com.ibm.as400.access.AS400;
023    import com.ibm.as400.access.AS400Message;
024    import com.ibm.as400.access.AS400Text;
025    import com.ibm.as400.access.ProgramCall;
026    import com.ibm.as400.access.ProgramParameter;
027    import org.apache.camel.Exchange;
028    import org.apache.camel.InvalidPayloadException;
029    import org.apache.camel.impl.DefaultProducer;
030    import org.apache.camel.util.ExchangeHelper;
031    import org.slf4j.Logger;
032    import org.slf4j.LoggerFactory;
033    
034    public class Jt400PgmProducer extends DefaultProducer {
035    
036        private static final Logger LOG = LoggerFactory.getLogger(Jt400PgmProducer.class);
037    
038        public Jt400PgmProducer(Jt400PgmEndpoint endpoint) {
039            super(endpoint);
040        }
041    
042        private Jt400PgmEndpoint getISeriesEndpoint() {
043            return (Jt400PgmEndpoint) super.getEndpoint();
044        }
045    
046        public void process(Exchange exchange) throws Exception {
047    
048            AS400 iSeries = getISeriesEndpoint().getiSeries();
049    
050            String commandStr = getISeriesEndpoint().getProgramToExecute();
051            ProgramParameter[] parameterList = getParameterList(exchange);
052    
053            ProgramCall pgmCall = new ProgramCall(iSeries);
054            pgmCall.setProgram(commandStr);
055            pgmCall.setParameterList(parameterList);
056    
057            if (LOG.isDebugEnabled()) {
058                LOG.trace("Starting to call PGM '{}' in host '{}' authentication with the user '{}'",
059                        new Object[]{commandStr, iSeries.getSystemName(), iSeries.getUserId()});
060            }
061    
062            boolean result = pgmCall.run();
063    
064            if (LOG.isTraceEnabled()) {
065                LOG.trace("Executed PGM '{}' in host '{}'. Success? {}", new Object[]{commandStr, iSeries.getSystemName(), result});
066            }
067    
068            if (result) {
069                handlePGMOutput(exchange, pgmCall, parameterList);
070            } else {
071                throw new Jt400PgmCallException(getOutputMessages(pgmCall));
072            }
073        }
074    
075        private ProgramParameter[] getParameterList(Exchange exchange) throws InvalidPayloadException {
076    
077            Object body = ExchangeHelper.getMandatoryInBody(exchange);
078    
079            String[] params = (String[]) body;
080    
081            ProgramParameter[] parameterList = new ProgramParameter[params.length];
082            for (int i = 0; i < params.length; i++) {
083                Object param = params[i];
084    
085                boolean input = param != null;
086                boolean output = getISeriesEndpoint().isFieldIdxForOuput(i);
087    
088                byte[] inputData = null;
089                int outputLength = -1;
090                if (input) {
091                    String value = (String) param;
092                    inputData = new AS400Text(value.length()).toBytes(value);
093                }
094                if (output) {
095                    outputLength = getISeriesEndpoint().getOutputFieldLength(i);
096                }
097    
098                if (input && output) {
099                    parameterList[i] = new ProgramParameter(inputData, outputLength);
100                }
101                if (input) {
102                    parameterList[i] = new ProgramParameter(inputData);
103                }
104                if (output) {
105                    parameterList[i] = new ProgramParameter(outputLength);
106                }
107            }
108    
109            return parameterList;
110        }
111    
112        private void handlePGMOutput(Exchange exchange, ProgramCall pgmCall, ProgramParameter[] inputs) throws InvalidPayloadException {
113    
114            Object bodyIN = ExchangeHelper.getMandatoryInBody(exchange);
115            String[] params = (String[]) bodyIN;
116    
117            List<String> results = new ArrayList<String>();
118    
119            int i = 1;
120            for (ProgramParameter pgmParam : pgmCall.getParameterList()) {
121                byte[] output = pgmParam.getOutputData();
122    
123                String value = params[i - 1];
124    
125                if (output != null) {
126                    int length = pgmParam.getOutputDataLength();
127    
128                    AS400Text text = new AS400Text(length);
129                    value = (String) text.toObject(output);
130                }
131    
132                results.add(value);
133                i++;
134            }
135    
136            String[] bodyOUT = new String[results.size()];
137            bodyOUT = results.toArray(bodyOUT);
138    
139            exchange.getOut().setBody(bodyOUT);
140        }
141    
142        private String getOutputMessages(ProgramCall pgmCall) throws Exception {
143            StringBuilder outputMsg = new StringBuilder();
144            // Show messages.
145            AS400Message[] messageList = pgmCall.getMessageList();
146            for (int i = 0; i < messageList.length; ++i) {
147                // Load additional message information.
148                messageList[i].load();
149                outputMsg.append(i + ") ");
150                outputMsg.append(messageList[i].getText());
151                outputMsg.append(" - ");
152                outputMsg.append(messageList[i].getHelp());
153                outputMsg.append("\n");
154            }
155            return outputMsg.toString();
156        }
157    
158        @Override
159        protected void doStart() throws Exception {
160            if (!getISeriesEndpoint().getiSeries().isConnected()) {
161                LOG.info("Connecting to " + getISeriesEndpoint());
162                getISeriesEndpoint().getiSeries().connectService(AS400.COMMAND);
163            }
164        }
165    
166        @Override
167        protected void doStop() throws Exception {
168            if (getISeriesEndpoint().getiSeries().isConnected()) {
169                LOG.info("Disconnecting from " + getISeriesEndpoint());
170                getISeriesEndpoint().getiSeries().disconnectAllServices();
171            }
172        }
173    
174    }