All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jkoolcloud.tnt4j.streams.custom.inputs.castiron.CastIronWsStream Maven / Gradle / Ivy

/*
 * Copyright 2014-2023 JKOOL, LLC.
 *
 * 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 com.jkoolcloud.tnt4j.streams.custom.inputs.castiron;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.xml.soap.*;

import com.jkoolcloud.tnt4j.core.OpLevel;
import com.jkoolcloud.tnt4j.sink.EventSink;
import com.jkoolcloud.tnt4j.streams.configure.WsStreamProperties;
import com.jkoolcloud.tnt4j.streams.inputs.WsStream;
import com.jkoolcloud.tnt4j.streams.scenario.WsScenario;
import com.jkoolcloud.tnt4j.streams.scenario.WsScenarioStep;
import com.jkoolcloud.tnt4j.streams.utils.*;

/**
 * Class implementing IBM Cast Iron WebService reported Logs, Jobs and other metrics streaming.
 * 

* This stream performs {@code "login"} request to obtain session identifier (token) used to retrieve metrics data. On * metrics retrieval request failure, {@code "login"} request is reissued. *

* Default metrics retrieval requests are issued sequentially: first - is requested a number of available entries, and * second - issuing "search" (list) request providing offset and number of entries to return. Other metrics retrieval * scenarios are possible by providing different scenario steps/requests configuration. *

* This activity stream requires parsers that can support {@link String} data to parse * {@link com.jkoolcloud.tnt4j.streams.scenario.WsResponse#getData()} provided string. *

* This activity stream supports the following configuration properties (in addition to those supported by * {@link com.jkoolcloud.tnt4j.streams.inputs.WsStream}): *

    *
  • SecurityCachedTokenKey - defines streams cache entry key referring {@code "login"} request received session ID * token. Default value - {@code "Token"}. (Optional)
  • *
  • SecurityResponseParserTag - defines tag value used to map {@code "login"} request data and parser used to parse * it. Default value - {@code "login"}. (Optional)
  • *
* * @version $Revision: 2 $ */ public class CastIronWsStream extends WsStream { private static final EventSink LOGGER = LoggerUtils.getLoggerSink(CastIronWsStream.class); private String tokenCacheKey = "Token"; // NON-NLS private String securityResponseParserTag = "login"; // NON-NLS private final Lock faultHandlingLock = new ReentrantLock(); @Override protected EventSink logger() { return LOGGER; } @Override public void setProperty(String name, String value) { super.setProperty(name, value); if (WsStreamProperties.PROP_SECURITY_CACHED_TOKEN_KEY.equalsIgnoreCase(name)) { tokenCacheKey = value; } else if (WsStreamProperties.PROP_SECURITY_RESPONSE_PARSER_TAG.equalsIgnoreCase(name)) { securityResponseParserTag = value; } } @Override public Object getProperty(String name) { if (WsStreamProperties.PROP_SECURITY_CACHED_TOKEN_KEY.equalsIgnoreCase(name)) { return tokenCacheKey; } if (WsStreamProperties.PROP_SECURITY_RESPONSE_PARSER_TAG.equalsIgnoreCase(name)) { return securityResponseParserTag; } return super.getProperty(name); } /** * Appends SOAP request message with {@code "sessionId"} header having token received from scenario {@code "login"} * step and saved in streams cache. * * @param soapRequest * SOAP request message instance * * @throws javax.xml.soap.SOAPException * if there was an error adding the SOAP message header */ @Override protected void addSoapHeaders(SOAPMessage soapRequest) throws SOAPException { SOAPFactory soapFactory = SOAPFactory.newInstance(); SOAPElement sessionIdElem = soapFactory.createElement("sessionId", "sec", // NON-NLS "http://www.approuter.com/schemas/2008/1/security"); // NON-NLS String cachedToken = String.valueOf(StreamsCache.getValue(tokenCacheKey)); logger().log(OpLevel.DEBUG, StreamsResources.getBundle(WsStreamConstants.RESOURCE_BUNDLE_NAME), "CastIronStream.adding.req.header", sessionIdElem.getLocalName(), cachedToken); sessionIdElem.setTextContent(cachedToken); soapRequest.getSOAPHeader().addChildElement(sessionIdElem); } /** * Handles response contained SOAP fault. If fault indicates expired/invalid session id reissues {@code "login"} * request. * * @param fault * SOAP fault to handle * @param scenario * scenario of failed request */ @Override protected void handleFault(SOAPFault fault, WsScenario scenario) { if (fault.getFaultString().equals("Expired or invalid session ID")) { // NON-NLS // TODO use code faultHandlingLock.lock(); try { if (scenario.getLoginStep() == null || scenario.getLoginStep().isEmpty()) { throw new RuntimeException( StreamsResources.getStringFormatted(WsStreamConstants.RESOURCE_BUNDLE_NAME, "CastIronStream.empty.login.step", scenario.getName())); } login(scenario.getLoginStep()); String cachedToken = String.valueOf(StreamsCache.getValue(tokenCacheKey)); throw new RuntimeException(StreamsResources.getStringFormatted(WsStreamConstants.RESOURCE_BUNDLE_NAME, "CastIronStream.logged.in.after.fault", scenario.getName(), cachedToken)); } finally { faultHandlingLock.unlock(); } } else { super.handleFault(fault, scenario); } } private void login(WsScenarioStep loginStep) { if (loginStep == null || loginStep.isEmpty()) { return; // TODO: ??? } try { RequestDataAndHeaders requestDataAndHeaders = new RequestDataAndHeaders() .resolve(fillInRequestData(loginStep.getRequests().get(0).getData())); SOAPMessage soapRequest = createMessage(requestDataAndHeaders.getRequest(), requestDataAndHeaders.getHeaders(), false); logger().log(OpLevel.INFO, StreamsResources.getBundle(WsStreamConstants.RESOURCE_BUNDLE_NAME), "CastIronStream.login.request", toXMLString(soapRequest)); SOAPMessage soapResponse = createSOAPConnection().call(soapRequest, fillInRequestData(loginStep.getUrlStr())); if (soapResponse.getSOAPBody().hasFault()) { logger().log(OpLevel.ERROR, StreamsResources.getBundle(WsStreamConstants.RESOURCE_BUNDLE_NAME), "CastIronStream.login.failed", soapResponse.getSOAPBody().getFault().getFaultString()); } String responseString = toXMLString(soapResponse); logger().log(OpLevel.INFO, StreamsResources.getBundle(WsStreamConstants.RESOURCE_BUNDLE_NAME), "CastIronStream.login.response", responseString); applyParsers(responseString, securityResponseParserTag); } catch (Throwable exc) { Utils.logThrowable(logger(), OpLevel.ERROR, StreamsResources.getBundle(WsStreamConstants.RESOURCE_BUNDLE_NAME), "CastIronStream.login.failed", exc); } } /** * Resolved tags values from SOAP received response data to map parsers to be used to parse it. Tag is SOAP response * message method name. * * @param data * activity data item to get tags * @return resolved data tags array, or {@code null} if there is no tags resolved */ @Override public String[] getDataTags(Object data) { try (InputStream is = new ByteArrayInputStream(String.valueOf(data).getBytes())) { SOAPMessage request = MessageFactory.newInstance().createMessage(null, is); String currentMethod = request.getSOAPBody().getFirstChild().getLocalName().replace("Response", ""); // NON-NLS logger().log(OpLevel.DEBUG, StreamsResources.getBundle(WsStreamConstants.RESOURCE_BUNDLE_NAME), "CastIronStream.parser.tag.resolved", currentMethod); return new String[] { currentMethod }; } catch (Throwable exc) { logger().log(OpLevel.ERROR, StreamsResources.getBundle(WsStreamConstants.RESOURCE_BUNDLE_NAME), "CastIronStream.parser.tag.resolve.failed", Utils.getExceptionMessages(exc), data); } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy