package uk.ac.imperial.lsds.seepworker.core.input; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.ac.imperial.lsds.seep.api.ConnectionType; import uk.ac.imperial.lsds.seep.api.DataReference; import uk.ac.imperial.lsds.seep.api.DataStoreType; import uk.ac.imperial.lsds.seep.api.data.Schema; import uk.ac.imperial.lsds.seep.comm.IOComm; import uk.ac.imperial.lsds.seep.core.IBuffer; import uk.ac.imperial.lsds.seep.core.InputAdapter; import uk.ac.imperial.lsds.seep.core.InputAdapterReturnType; import uk.ac.imperial.lsds.seepcontrib.kafka.comm.KafkaDataStream; import uk.ac.imperial.lsds.seepworker.WorkerConfig; import uk.ac.imperial.lsds.seepworker.core.DataReferenceManager; import uk.ac.imperial.lsds.seepworker.core.Dataset; public class InputAdapterFactory { // FIXME: refactor -> all inputadapters that are per buffer do the same. code reuse final static private Logger LOG = LoggerFactory.getLogger(IOComm.class.getName()); public static List<InputAdapter> buildInputAdapterForStreamId(WorkerConfig wc, int streamId, List<IBuffer> buffers, Set<DataReference> drefs, ConnectionType connType, DataReferenceManager drm) { List<InputAdapter> ias = new ArrayList<>(); List<InputAdapter> ias_dataset = new ArrayList<>(); List<InputAdapter> ias_network = new ArrayList<>(); List<InputAdapter> ias_file = new ArrayList<>(); List<InputAdapter> ias_kafka = new ArrayList<>(); List<Dataset> datasets = new ArrayList<>(); List<IBuffer> network_buffers = new ArrayList<>(); List<IBuffer> file_buffers = new ArrayList<>(); List<IBuffer> kafka_buffers = new ArrayList<>(); for(IBuffer ib : buffers) { DataReference dRef = ib.getDataReference(); boolean dRefManaged = dRef.isManaged(); DataStoreType type = dRef.getDataStore().type(); // Exception, when SYNTHETIC, simply add Dataset and continue if(type.equals(DataStoreType.SEEP_SYNTHETIC_GEN)) { // ((Dataset)ib).markAcess(); datasets.add((Dataset)ib); continue; } // Exception, when ib is FacadeInputBuffer, simply add the InputAdapter and continue if(ib instanceof FacadeInputBuffer) { InputAdapter ia = buildFacadeInputAdapter(streamId, ib); ias.add(ia); // add directly here continue; } if(dRefManaged) { // The DR is managed by SEEP if(drm.doesManageDataReference(dRef.getId()) != null) { // In this node. We should have a dataset if(! (ib instanceof Dataset)) { // throw error } // ((Dataset)ib).markAcess(); datasets.add((Dataset)ib); } else { // If NOT in this node. Request a NETWORK conn and we should have InputBuffer if(! (ib instanceof InputBuffer)) { // throw error } network_buffers.add(ib); } } else if(!dRefManaged) { if (type.equals(DataStoreType.NETWORK)) { network_buffers.add(ib); } else if(type.equals(DataStoreType.FILE)) { file_buffers.add(ib); } else if(type.equals(DataStoreType.KAFKA)) { kafka_buffers.add(ib); } } } if(! datasets.isEmpty()) { ias_dataset = buildInputAdapterOfTypeDatasetForOps(wc, streamId, drefs, datasets); } if(! network_buffers.isEmpty()) { ias_network = buildInputAdapterOfTypeNetworkForOps(wc, streamId, drefs, network_buffers, connType); } if(! file_buffers.isEmpty()) { ias_file = buildInputAdapterOfTypeFileForOps(wc, streamId, drefs, file_buffers, connType); } if(! kafka_buffers.isEmpty()) { ias_kafka = buildInputAdapterOfTypeKafkaForOps(wc, streamId, drefs, kafka_buffers, connType); } ias.addAll(ias_dataset); ias.addAll(ias_network); ias.addAll(ias_file); ias.addAll(ias_kafka); return ias; } private static InputAdapter buildFacadeInputAdapter(int streamId, IBuffer buffer) { // Check how to pass the return type information InputAdapter ia = new FacadeInputAdapter(streamId, InputAdapterReturnType.ONE, buffer); return ia; } private static List<InputAdapter> buildInputAdapterOfTypeDatasetForOps( WorkerConfig wc, int streamId, Set<DataReference> drefs, List<Dataset> datasets){ List<InputAdapter> ias = new ArrayList<>(); for(Dataset dataset : datasets) { InputAdapter ia = new DatasetInputAdapter(wc, streamId, dataset); ias.add(ia); } return ias; } private static List<InputAdapter> buildInputAdapterOfTypeNetworkForOps( WorkerConfig wc, int streamId, Set<DataReference> drefs, List<IBuffer> buffers, ConnectionType connType) { List<InputAdapter> ias = new ArrayList<>(); short cType = connType.ofType(); Schema expectedSchema = drefs.iterator().next().getDataStore().getSchema(); if(cType == ConnectionType.ONE_AT_A_TIME.ofType()) { // one-queue-per-conn, one-single-queue, etc. LOG.info("Creating NETWORK inputAdapter for upstream streamId: {} of type {}", streamId, "ONE_AT_A_TIME"); for(IBuffer buffer : buffers) { InputAdapter ia = new NetworkDataStream(wc, streamId, buffer, expectedSchema); ias.add(ia); } } else if(cType == ConnectionType.UPSTREAM_SYNC_BARRIER.ofType()) { LOG.info("Creating NETWORK inputAdapter for upstream streamId: {} of type {}", streamId, "UPSTREAM_SYNC_BARRIER"); InputAdapter ia = new NetworkBarrier(wc, streamId, buffers, expectedSchema); ias.add(ia); } return ias; } private static List<InputAdapter> buildInputAdapterOfTypeFileForOps( WorkerConfig wc, int streamId, Set<DataReference> drefs, List<IBuffer> buffers, ConnectionType connType) { List<InputAdapter> ias = new ArrayList<>(); short cType = connType.ofType(); Schema expectedSchema = drefs.iterator().next().getDataStore().getSchema(); if(cType == ConnectionType.ONE_AT_A_TIME.ofType()) { // one-queue-per-conn, one-single-queue, etc. LOG.info("Creating FILE inputAdapter for upstream streamId: {} of type {}", streamId, "ONE_AT_A_TIME"); for(IBuffer buffer : buffers) { InputAdapter ia = new FileDataStream(wc, streamId, buffer, expectedSchema); ias.add(ia); } } return ias; } private static List<InputAdapter> buildInputAdapterOfTypeKafkaForOps( WorkerConfig wc, int streamId, Set<DataReference> drefs, List<IBuffer> buffers, ConnectionType connType) { List<InputAdapter> ias = new ArrayList<>(); short cType = connType.ofType(); Schema expectedSchema = drefs.iterator().next().getDataStore().getSchema(); if(cType == ConnectionType.ONE_AT_A_TIME.ofType()) { // one-queue-per-conn, one-single-queue, etc. LOG.info("Creating KAFKA inputAdapter for upstream streamId: {} of type {}", streamId, "ONE_AT_A_TIME"); for(IBuffer buffer : buffers) { InputAdapter ia = new KafkaDataStream(streamId, buffer, expectedSchema); ias.add(ia); } } return ias; } }