/*
   Copyright 2017 Nationale-Nederlanden

   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 nl.nn.adapterframework.extensions.api;

import org.apache.commons.lang3.StringUtils;

import nl.nn.adapterframework.configuration.ConfigurationException;
import nl.nn.adapterframework.configuration.IbisContext;
import nl.nn.adapterframework.core.IPipeLineSession;
import nl.nn.adapterframework.core.PipeRunException;
import nl.nn.adapterframework.jdbc.FixedQuerySender;
import nl.nn.adapterframework.jdbc.JdbcException;
import nl.nn.adapterframework.jdbc.JdbcTransactionalStorage;
import nl.nn.adapterframework.parameters.ParameterResolutionContext;
import nl.nn.adapterframework.pipes.StreamPipe;
import nl.nn.adapterframework.util.AppConstants;
import nl.nn.adapterframework.util.JdbcUtil;
import nl.nn.adapterframework.util.XmlUtils;

/**
 * Extension to StreamPipe for API Management.
 *
 * @author Peter Leeuwenburgh
 */

public class ApiStreamPipe extends StreamPipe {
	private String jmsRealm;

	private FixedQuerySender dummyQuerySender;

	@Override
	public void configure() throws ConfigurationException {
		setExtractFirstStringPart(true);
		super.configure();
	}

	@Override
	protected String adjustFirstStringPart(String firstStringPart,
			IPipeLineSession session) throws PipeRunException {
		if (firstStringPart == null) {
			return "";
		} else {
			boolean retrieveMessage = false;
			if (XmlUtils.isWellFormed(firstStringPart, "MessageID")) {
				String rootNamespace = XmlUtils
						.getRootNamespace(firstStringPart);
				if ("http://www.w3.org/2005/08/addressing"
						.equals(rootNamespace)) {
					retrieveMessage = true;
				}
			}
			if (retrieveMessage) {
				String messageId = null;
				try {
					messageId = XmlUtils.evaluateXPathNodeSetFirstElement(
							firstStringPart, "MessageID");
				} catch (Exception e) {
					throw new PipeRunException(this,
							"Exception getting MessageID", e);
				}
				if (StringUtils.isEmpty(messageId)) {
					throw new PipeRunException(this,
							"Could not find messageId in request ["
									+ firstStringPart + "]");
				} else {
					// TODO: create dummyQuerySender should be put in
					// configure(), but gives an error
					IbisContext ibisContext = getAdapter().getConfiguration()
							.getIbisManager().getIbisContext();
					dummyQuerySender = (FixedQuerySender) ibisContext
							.createBeanAutowireByName(FixedQuerySender.class);
					dummyQuerySender.setJmsRealm(jmsRealm);
					dummyQuerySender
							.setQuery("SELECT count(*) FROM ALL_TABLES");
					try {
						dummyQuerySender.configure();
					} catch (ConfigurationException e) {
						throw new PipeRunException(this,
								"Exception configuring dummy query sender", e);
					}

					ParameterResolutionContext prc = new ParameterResolutionContext(
							"", session);
					String slotId = AppConstants.getInstance()
							.getResolvedProperty("instance.name") + "/"
							+ session.get("operation");
					String selectMessageKeyResult = null;
					try {
						selectMessageKeyResult = selectMessageKey(slotId,
								messageId);
					} catch (Exception e) {
						throw new PipeRunException(this,
								"Exception getting messageKey", e);
					}
					if (StringUtils.isEmpty(selectMessageKeyResult)) {
						throw new PipeRunException(this,
								"Could not find message in MessageStore for slotId ["
										+ slotId + "] and messageId ["
										+ messageId + "]");
					} else {
						String selectMessageResult = null;
						try {
							selectMessageResult = selectMessage(
									selectMessageKeyResult);
						} catch (Exception e) {
							throw new PipeRunException(this,
									"Exception getting message", e);
						}
						if (StringUtils.isEmpty(selectMessageResult)) {
							throw new PipeRunException(this,
									"Could not find message in MessageStore with messageKey ["
											+ selectMessageKeyResult + "]");
						} else {
							try {
								deleteMessage(selectMessageKeyResult);
							} catch (Exception e) {
								throw new PipeRunException(this,
										"Exception deleting message", e);
							}
						}
						return selectMessageResult;
					}
				}
			} else {
				return firstStringPart;
			}
		}
	}

	private String selectMessageKey(String slotId, String messageId)
			throws JdbcException {
		String query = "SELECT MESSAGEKEY FROM IBISSTORE WHERE TYPE='"
				+ JdbcTransactionalStorage.TYPE_MESSAGESTORAGE
				+ "' AND SLOTID='" + slotId + "' AND MESSAGEID='" + messageId
				+ "'";
		return JdbcUtil.executeStringQuery(dummyQuerySender.getConnection(),
				query);
	}

	private String selectMessage(String messageKey) throws JdbcException {
		String query = "SELECT MESSAGE FROM IBISSTORE WHERE MESSAGEKEY='"
				+ messageKey + "'";
		return JdbcUtil.executeBlobQuery(dummyQuerySender.getConnection(),
				query);
	}

	private void deleteMessage(String messageKey) throws JdbcException {
		String query = "DELETE FROM IBISSTORE WHERE MESSAGEKEY='" + messageKey
				+ "'";
		JdbcUtil.executeStatement(dummyQuerySender.getConnection(), query);
	}

	public String getJmsRealm() {
		return jmsRealm;
	}

	public void setJmsRealm(String jmsRealm) {
		this.jmsRealm = jmsRealm;
	}

}

@@ -1389,16 +1389,432 @@
 gement.%0A
+ * %3Cbr/%3E%0A * In %7B@link nl.nn.adapterframework.pipes.StreamPipe%7D for parameter %3Ccode%3EhttpRequest%3C/code%3E and attribute %0A * %3Ccode%3EextractFirstStringPart=true%3C/code%3E the first part is returned to the pipeline.%0A * In this class the first part is checked. If it contains a 'MessageID' with namespace %22http://www.w3.org/2005/08/addressing%22,%0A * then the message to return to the pipeline is retrieved from the MessageStore. %0A
  *%0A * @a

Fix javadoc