-
Notifications
You must be signed in to change notification settings - Fork 4
Added conversation import web service #37
base: develop
Are you sure you want to change the base?
Conversation
- initial check-in
- correct version in pom files
…Kurz/smarti into feature/json-message-importer
- correct version in pom files
private static final DateFormat ISODateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); | ||
|
||
@Autowired | ||
private ConversationWebservice conversationWebservice; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not use Webservices in a Service. Use the conversationService instead.
StringBuffer input = new StringBuffer(); | ||
input.append(I_ImporterService.JSON_RESULT_WRAPPER_START); | ||
|
||
while (iterator.hasNext()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be more elegant with guava, java 8 ..., like e.g.:
ImmutableList.copyOf(iterator).stream().map(Document::toJson).collect(Collectors.joining(","));
Or you could use JacksonMapper (as the Document implements map) for the whole thing like:
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(Collections.singletonMap("export",ImmutableList.copyOf(iterator)));
(untested code !;)
import io.redlink.smarti.services.importer.I_ConversationSource; | ||
import io.redlink.smarti.services.importer.I_ConversationTarget; | ||
|
||
public interface I_ImporterService { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should find a common way of classnaming. In other projects we used to use NAME for interfaces and NAMEImpl for implementations. But I like this approach. But at least we should bring everything to a one naming scheme.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would put the Interface in another package (e.g. api)
private RocketChatEndpoint rcEndpoint; | ||
|
||
public ImporterService() { | ||
rcEndpoint = new RocketChatEndpoint(null, 0, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use spring to manage your service beans. The best way is:
private RocketChatEndpoint rcEndpoint;
public ImporterService(@Autowired RocketChatEndpoint rcEndpoint) {
this.rcEndpoint = rcEndpoint;
}
log.info("Start export at : " + (new Date().getTime() - time) + " ms"); | ||
String export = source.exportConversations(); | ||
log.info("Start parsing at : " + (new Date().getTime() - time) + " ms"); | ||
JSONObject eportedJSON = (JSONObject) new JSONParser().parse(export); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why source.exportConversation does not create an Object directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea was to avoid duplicated code, since
JSONObject eportedJSON = (JSONObject) new JSONParser().parse(export);
would be the same in each Source implementation.
Could you please provide some arguments why you'll expect the Source itself should create the Object?
* | ||
* @throws Exception if something goes wrong | ||
*/ | ||
String exportConversations() throws Exception; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could return an object (as already mentioned)
ObjectMapper mapper = new ObjectMapper(); | ||
|
||
try { | ||
E_SourceType type = E_SourceType.valueOf(sourceType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be done nicer with a factory
public JSONObject asJSON() { | ||
|
||
try { | ||
return (JSONObject) new JSONParser().parse(new ObjectMapper().writeValueAsString(this)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need this? As far as I can see you always use the toJsonString method on things produces by this method. So a direct serialization with ObjectMapper is more straight forward.
import com.fasterxml.jackson.annotation.JsonPropertyOrder; | ||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
@JsonPropertyOrder({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the order of properties matters?
} | ||
|
||
@Test | ||
public void testJSONFile() throws ClientProtocolException, IOException, Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is not test right ;) So no assertions oa. If you want to do a nearly full integration which is still testable you could mock the conversation repository. Or test the units and mock the services. e.g. with Mockito.
One thing is absolutely necessary to change: There are services which uses webservices (which is not a good style) which itself use services again. You should use services directly. Some things can be more elegant. The import interface could be rethought. |
- corrections from review - Do not use Webservices in a Service. - Use spring to manage your service beans. - Just use the ConversationService and Message object. - Use JacksonMapper / direct serialization with ObjectMapper - Removed order from JSON/Beans
What's missing here, let me summarize: Major implementation issues
Minor implementation issues
Missing documentation and tests
Overall comment
A good importer .... The code for export as well as a scheduler should not be part of the Smarti project. A interface could look like:
Implementing such an interface would allow to externalize the knowledge of exporting different source systems into third party libs. What would keep the code of Smarti clean! |
@tkurz did you have a chance to have a closer look into this PR? |
This commit adds an importer web service to the Smarti Backend application.
This implementation is a first draft and not yet final. Any comments are appreciated.
solves #36
Usage:
1. Importing a JSON file that has been exported from a Rocket.Chat MongoDB
The file import can handle Rocket.Chat MongoDB exported JSON that can be crated like this:
2. Importing direct from RocketChat MongoDB
3. Importing from Rocket.Chat Webservice
The idea is to use the REST API of Rocket.Chat to get conversations that will be than imported into Smarti. In the current commit this importer is not finished yet.
4. Importing from Slack or other chat platforms
5. Importing from E-Mail server (Pop/Imap)
6. Importing via web crawler, e.g. FAQ-websites