/**
* Copyright 2007-2015, Kaazing Corporation. All rights reserved.
*
* 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.kaazing.k3po.pcap.converter.internal.author;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Logger;
import org.kaazing.k3po.pcap.converter.internal.author.composer.ComposerFactory;
import org.kaazing.k3po.pcap.converter.internal.author.composer.GenericComposerFactory;
import org.kaazing.k3po.pcap.converter.internal.author.coordinator.Coordinator;
import org.kaazing.k3po.pcap.converter.internal.author.coordinator.CoordinatorFactory;
import org.kaazing.k3po.pcap.converter.internal.author.coordinator.CoordinatorFactoryImpl;
import org.kaazing.k3po.pcap.converter.internal.author.emitter.Emitter;
import org.kaazing.k3po.pcap.converter.internal.author.emitter.EmitterFactory;
import org.kaazing.k3po.pcap.converter.internal.author.emitter.EmitterFactoryImpl;
import org.kaazing.k3po.pcap.converter.internal.author.emitter.OutputType;
import org.kaazing.k3po.pcap.converter.internal.packet.Packet;
import org.kaazing.k3po.pcap.converter.internal.parser.Parser;
/**
* RptScriptsCreator
*
* Creates the Rupert Scripts by feeding it a packet at a time
*
*/
public class RptScriptCreator {
private final static Logger LOG = Logger.getLogger(Parser.class.getName());
private final Map<ConversationId, Stack<Coordinator>> coordinators;
private final EmitterFactory emitterFactory;
private final CoordinatorFactory coordinatorFactory;
private final String CREATOR_NOTE_HEADER = "See subfolders for more specific scripts, see READMEs for what each dir contains \n\n"
+ "Scripts saved in this folder correspond to a complete interaction on a node qualified \n"
+ "by either protocol and/or the side (client/server) of conversation \n "
+ "ex)\t ip1.rpt will have all interaction on a node \n"
+ "\t ip1-tcp.rpt will have all tcp interaction on a node \n"
+ "\t ip1-tcp-server.rpt will have all tcp server interaction on a node \n";
private final Emitter creatorNote;
public RptScriptCreator() {
emitterFactory = new EmitterFactoryImpl();
ComposerFactory composerFactory = new GenericComposerFactory(emitterFactory);
coordinatorFactory = new CoordinatorFactoryImpl(composerFactory, emitterFactory);
creatorNote = emitterFactory.getNoteEmitter(OutputType.CREATOR, CREATOR_NOTE_HEADER);
coordinators = new HashMap<>();
}
public RptScriptCreator(EmitterFactory emitterFactory, CoordinatorFactory coordinatorFactory){
this.emitterFactory = emitterFactory;
this.coordinatorFactory = coordinatorFactory;
creatorNote = emitterFactory.getNoteEmitter(OutputType.CREATOR, CREATOR_NOTE_HEADER);
coordinators = new HashMap<>();
}
public void addPacketToScripts(Packet packet) {
LOG.info("Emitting packet " + packet.getPacketNumber());
if ( packet.isTcp() ) {
LOG.info("Emitting tcp packet");
ConversationId conversationId = new ConversationId(packet, SupportedProtocol.TCP);
if ( !coordinators.containsKey(conversationId) ) { // if no key for host pair create it
coordinators.put(conversationId, new Stack<Coordinator>());
}
Stack<Coordinator> set = coordinators.get(conversationId);
if ( set.empty() || set.peek().isFinished() ) {
Coordinator coordinator = coordinatorFactory.getCoordinator(conversationId);
coordinator.startScript(packet);
set.push(coordinator);
coordinators.put(conversationId, set);
}
else {
set.peek().conversation(packet);
}
return;
}
return;
}
public void commitToFile() {
for (Stack<Coordinator> stack : coordinators.values()) {
for (Coordinator cord : stack) {
cord.commitToFile();
}
}
KeyToEmitterHashMap topLevelEmitters = new KeyToEmitterHashMap();
for (ConversationId convId : coordinators.keySet()) {
topLevelEmitters.put(convId.getIpAddr1());
topLevelEmitters.put(convId.getIpAddr2());
// tcp
topLevelEmitters.put(convId.getIpAddr1() + "-" + convId.getProtocol());
topLevelEmitters.put(convId.getIpAddr1() + "-" + convId.getProtocol() + "-server");
topLevelEmitters.put(convId.getIpAddr1() + "-" + convId.getProtocol() + "-client");
topLevelEmitters.put(convId.getIpAddr2() + "-" + convId.getProtocol());
topLevelEmitters.put(convId.getIpAddr2() + "-" + convId.getProtocol() + "-server");
topLevelEmitters.put(convId.getIpAddr2() + "-" + convId.getProtocol() + "-client");
}
for (ConversationId convId : coordinators.keySet()) {
creatorNote.add((convId.getName() + "\n"));
for (Coordinator coordinator : coordinators.get(convId)) {
topLevelEmitters.get(convId.getIpAddr1() + "-" + convId.getProtocol()).add(
coordinator.getScriptsByIp(convId.getIpAddr1()));
topLevelEmitters.get(convId.getIpAddr2() + "-" + convId.getProtocol()).add(
coordinator.getScriptsByIp(convId.getIpAddr2()));
topLevelEmitters.get(convId.getIpAddr1() + "-" + convId.getProtocol() + "-server").add(
coordinator.getServerScriptsByIp(convId.getIpAddr1()));
topLevelEmitters.get(convId.getIpAddr2() + "-" + convId.getProtocol() + "-server").add(
coordinator.getServerScriptsByIp(convId.getIpAddr2()));
topLevelEmitters.get(convId.getIpAddr1() + "-" + convId.getProtocol() + "-client").add(
coordinator.getClientScriptsByIp(convId.getIpAddr1()));
topLevelEmitters.get(convId.getIpAddr2() + "-" + convId.getProtocol() + "-client").add(
coordinator.getClientScriptsByIp(convId.getIpAddr2()));
}
}
creatorNote.commitToFile();
for (Emitter emitter : topLevelEmitters.values()) {
emitter.commitToFile();
}
}
/**
* Special HashMap where key matches emitter's name (ie the value's name)
*
*/
private class KeyToEmitterHashMap extends HashMap<String, Emitter> {
private static final long serialVersionUID = 1L;
@Override
public Emitter put(String key, Emitter value) {
throw new RptScriptsCreatorFailureException(
"Misuse of this Class, This method is not implemented for this special hashmap");
}
public Emitter put(String key) {
if ( !containsKey(key) ) {
super.put(key, emitterFactory.getRptScriptEmitter(OutputType.CREATOR, key));
}
return get(key);
}
}
public void saveMemory() {
emitterFactory.setMemSaver(true);
}
}