I cant change the mapping. Can anybody help me to find the bug in my code?
I have found this standard way to change the mapping according to several tutorials. But when i'm try to call the mapping structure there just appear a blank mapping structure after manuall mapping creation.
But after inserting some data there appear the mapping specification because ES is using of course the default one. To be more specific see the code below.
public class ElasticTest {
private String dbname = "ElasticSearch";
private String index = "indextest";
private String type = "table";
private Client client = null;
private Node node = null;
public ElasticTest(){
this.node = nodeBuilder().local(true).node();
this.client = node.client();
if(isIndexExist(index)){
deleteIndex(this.client, index);
createIndex(index);
}
else{
createIndex(index);
}
System.out.println("mapping structure before data insertion");
getMappings();
System.out.println("----------------------------------------");
createData();
System.out.println("mapping structure after data insertion");
getMappings();
}
public void getMappings() {
ClusterState clusterState = client.admin().cluster().prepareState()
.setFilterIndices(index).execute().actionGet().getState();
IndexMetaData inMetaData = clusterState.getMetaData().index(index);
MappingMetaData metad = inMetaData.mapping(type);
if (metad != null) {
try {
String structure = metad.getSourceAsMap().toString();
System.out.println(structure);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void createIndex(String index) {
XContentBuilder typemapping = buildJsonMappings();
String mappingstring = null;
try {
mappingstring = buildJsonMappings().string();
} catch (IOException e1) {
e1.printStackTrace();
}
client.admin().indices().create(new CreateIndexRequest(index)
.mapping(type, typemapping)).actionGet();
//try put mapping after index creation
/*
* PutMappingResponse response = null; try { response =
* client.admin().indices() .preparePutMapping(index) .setType(type)
* .setSource(typemapping.string()) .execute().actionGet(); } catch
* (ElasticSearchException e) { e.printStackTrace(); } catch
* (IOException e) { e.printStackTrace(); }
*/
}
private void deleteIndex(Client client, String index) {
try {
DeleteIndexResponse delete = client.admin().indices()
.delete(new DeleteIndexRequest(index)).actionGet();
if (!delete.isAcknowledged()) {
} else {
}
} catch (Exception e) {
}
}
private XContentBuilder buildJsonMappings(){
XContentBuilder builder = null;
try {
builder = XContentFactory.jsonBuilder();
builder.startObject()
.startObject("properties")
.startObject("ATTR1")
.field("type", "string")
.field("store", "yes")
.field("index", "analyzed")
.endObject()
.endObject()
.endObject();
} catch (IOException e) {
e.printStackTrace();
}
return builder;
}
private boolean isIndexExist(String index) {
ActionFuture<IndicesExistsResponse> exists = client.admin().indices()
.exists(new IndicesExistsRequest(index));
IndicesExistsResponse actionGet = exists.actionGet();
return actionGet.isExists();
}
private void createData(){
System.out.println("Data creation");
IndexResponse response=null;
for (int i=0;i<10;i++){
Map<String, Object> json = new HashMap<String, Object>();
json.put("ATTR1", "new value" + i);
response = this.client.prepareIndex(index, type)
.setSource(json)
.setOperationThreaded(false)
.execute()
.actionGet();
}
String _index = response.getIndex();
String _type = response.getType();
long _version = response.getVersion();
System.out.println("Index : "+_index+" Type : "+_type+" Version : "+_version);
System.out.println("----------------------------------");
}
public static void main(String[] args)
{
new ElasticTest();
}
}
I just wanna change the property of ATTR1 field to analyzed to ensure fast queries.
What im doing wrong? I also tried to create the mapping after index creation but it leads to the same affect.
Ok i found the answer by my own. On the type level i had to wrap the "properties" with the type name. E.g:
"type1" : {
"properties" : {
.....
}
}
See the following code:
private XContentBuilder getMappingsByJson(){
XContentBuilder builder = null;
try {
builder = XContentFactory.jsonBuilder().startObject().startObject(type).startObject("properties");
for(int i = 1; i<5; i++){
builder.startObject("ATTR" + i)
.field("type", "integer")
.field("store", "yes")
.field("index", "analyzed")
.endObject();
}
builder.endObject().endObject().endObject();
}
catch (IOException e) {
e.printStackTrace();
}
return builder;
}
It creates mappings for the attributes ATTR1 - ATTR4. Now it is possible to define mapping for Example a list of different attributes dynamically. Hope it helps someone else.
Related
Hi I'm trying to make a PACS server using Java. dcm4che appears to be quite popular. But I'm unable to find any good examples about it.
As a starting point I inspected dcmqrscp and it successfully stores a DICOM image. But I cannot manage to handle a C-MOVE call. Here's my CMove handler. It finds requested the DICOM file adds a URL and other stuff, it doesn't throw any exception yet client doesn't receive any files.
private final class CMoveSCPImpl extends BasicCMoveSCP {
private final String[] qrLevels;
private final QueryRetrieveLevel rootLevel;
public CMoveSCPImpl(String sopClass, String... qrLevels) {
super(sopClass);
this.qrLevels = qrLevels;
this.rootLevel = QueryRetrieveLevel.valueOf(qrLevels[0]);
}
#Override
protected RetrieveTask calculateMatches(Association as, PresentationContext pc, final Attributes rq, Attributes keys) throws DicomServiceException {
QueryRetrieveLevel level = QueryRetrieveLevel.valueOf(keys, qrLevels);
try {
level.validateRetrieveKeys(keys, rootLevel, relational(as, rq));
} catch (Exception e) {
e.printStackTrace();
}
String moveDest = rq.getString(Tag.MoveDestination);
final Connection remote = new Connection("reciverAE",as.getSocket().getInetAddress().getHostAddress(), 11113);
if (remote == null)
throw new DicomServiceException(Status.MoveDestinationUnknown, "Move Destination: " + moveDest + " unknown");
List<T> matches = DcmQRSCP.this.calculateMatches(keys);
if (matches.isEmpty())
return null;
AAssociateRQ aarq;
Association storeas = null;
try {
aarq = makeAAssociateRQ(as.getLocalAET(), moveDest, matches);
storeas = openStoreAssociation(as, remote, aarq);
} catch (Exception e) {
e.printStackTrace();
}
BasicRetrieveTask<T> retrieveTask = null;
retrieveTask = new BasicRetrieveTask<T>(Dimse.C_MOVE_RQ, as, pc, rq, matches, storeas, new BasicCStoreSCU<T>());
retrieveTask.setSendPendingRSPInterval(getSendPendingCMoveInterval());
return retrieveTask;
}
private Association openStoreAssociation(Association as, Connection remote, AAssociateRQ aarq)
throws DicomServiceException {
try {
return as.getApplicationEntity().connect(as.getConnection(),
remote, aarq);
} catch (Exception e) {
throw new DicomServiceException(
Status.UnableToPerformSubOperations, e);
}
}
private AAssociateRQ makeAAssociateRQ(String callingAET,
String calledAET, List<T> matches) {
AAssociateRQ aarq = new AAssociateRQ();
aarq.setCalledAET(calledAET);
aarq.setCallingAET(callingAET);
for (InstanceLocator match : matches) {
if (aarq.addPresentationContextFor(match.cuid, match.tsuid)) {
if (!UID.ExplicitVRLittleEndian.equals(match.tsuid))
aarq.addPresentationContextFor(match.cuid,
UID.ExplicitVRLittleEndian);
if (!UID.ImplicitVRLittleEndian.equals(match.tsuid))
aarq.addPresentationContextFor(match.cuid,
UID.ImplicitVRLittleEndian);
}
}
return aarq;
}
private boolean relational(Association as, Attributes rq) {
String cuid = rq.getString(Tag.AffectedSOPClassUID);
ExtendedNegotiation extNeg = as.getAAssociateAC().getExtNegotiationFor(cuid);
return QueryOption.toOptions(extNeg).contains(
QueryOption.RELATIONAL);
}
}
I added the code below to send a DICOM file as a response:
String cuid = rq.getString(Tag.AffectedSOPClassUID);
String iuid = rq.getString(Tag.AffectedSOPInstanceUID);
String tsuid = pc.getTransferSyntax();
try {
DcmQRSCP.this.as=as;
File f = new File("D:\\dcmqrscpTestDCMDir\\1.2.840.113619.2.30.1.1762295590.1623.978668949.886\\1.2.840.113619.2.30.1.1762295590.1623.978668949.887\\1.2.840.113619.2.30.1.1762295590.1623.978668949.888");
FileInputStream in = new FileInputStream(f);
InputStreamDataWriter data = new InputStreamDataWriter(in);
// !1! as.cmove(cuid,1,keys,tsuid,"STORESCU");
as.cstore(cuid,iuid,1,data,tsuid,rspHandlerFactory.createDimseRSPHandler(f));
} catch (Exception e) {
e.printStackTrace();
}
Throws this exception
org.dcm4che3.net.NoRoleSelectionException: No Role Selection for SOP Class 1.2.840.10008.5.1.4.1.2.2.2 - Study Root Query/Retrieve Information Model - MOVE as SCU negotiated
You should add a role to the application instance like:
applicationEntity.addTransferCapability(
new TransferCapability(null, "*", TransferCapability.Role.SCP, "*"));
Good day, everyone! I have a little question about testing and generating a stub for dependence through reflection. So let's assume I have a class named UnderTest:
class UnderTest{
/*field*/
SomeLogic someLogic;
/*method, that i testing*/
List<MyObject> getCalculatedObjects(params) {/*logic,based on result getSomeStuff of someLogic*/ }
}
class SomeLogic {
List<String> getSomeStuff(String param) { /*Some complex and slow code, actually don't want test this code, and want to use some reflection invocation handler*/ }
}
For me it's important to not change legacy code, which doesn't design for testing. And i don't have any reason, except testing to make SomeLogic as an interface and so on.
I can't remember how to handle method invocation of someLogic using reflection. But google search isn't helping me.
Class MainAPI is... main api of my module. NetworkProvider long open stream operation, that's why i want to stub it, on my local files. But don't using directly reference on NetworkProvider. Again sorry for my English.
public class MainAPI {
private final XPath xPath;
private final ItemParser itemParser;
private final ListItemsParser listItemsParser;
private final DateParser dateParser;
private final HtmlCleanUp htmlCleanUp;
private final NetworkProvider networkProvider;
public MainAPI(XPath xPath, ItemParser itemParser, ListItemsParser listItemsParser, DateParser dateParser, HtmlCleanUp htmlCleanUp, NetworkProvider networkProvider) {
this.xPath = xPath;
this.itemParser = itemParser;
this.listItemsParser = listItemsParser;
this.dateParser = dateParser;
this.htmlCleanUp = htmlCleanUp;
this.networkProvider = networkProvider;
}
public MainAPI() throws XPathExpressionException, IOException {
dateParser = new DateParser();
xPath = XPathFactory.newInstance().newXPath();
networkProvider = new NetworkProvider();
listItemsParser = new ListItemsParser(xPath, dateParser, item -> true);
itemParser = new ItemParser(xPath, dateParser, networkProvider);
htmlCleanUp = new HtmlCleanUpByCleaner();
}
public List<Item> getItemsFromSessionParsing(SessionParsing sessionParsing) {
listItemsParser.setCondition(sessionParsing.getFilter());
List<Item> result = new ArrayList<>();
Document cleanDocument;
InputStream inputStream;
for (int currentPage = sessionParsing.getStartPage(); currentPage <= sessionParsing.getLastPage(); currentPage++) {
try {
inputStream = networkProvider.openStream(sessionParsing.getUrlAddressByPageNumber(currentPage));
} catch (MalformedURLException e) {
e.printStackTrace();
break;
}
cleanDocument = htmlCleanUp.getCleanDocument(inputStream);
List<Item> list = null;
try {
list = listItemsParser.getList(cleanDocument);
} catch (XPathExpressionException e) {
e.printStackTrace();
break;
}
for (Item item : list) {
inputStream = null;
try {
inputStream = networkProvider.openStream("http://www.avito.ru" + item.getUrl());
} catch (MalformedURLException e) {
e.printStackTrace();
break;
}
cleanDocument = htmlCleanUp.getCleanDocument(inputStream);
try {
item.setDescription(itemParser.getDescription(cleanDocument));
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
result.addAll(list);
}
return result;
}
}
public class NetworkProvider {
private final ListCycleWrapper<Proxy> proxyList;
public NetworkProvider(List<Proxy> proxyList) {
this.proxyList = new ListCycleWrapper<>(proxyList);
}
public NetworkProvider() throws XPathExpressionException, IOException {
this(new ProxySiteParser().getProxyList(new HtmlCleanUpByCleaner().getCleanDocument(new URL("http://www.google-proxy.net").openStream())));
}
public int getSizeOfProxy() {
return proxyList.size();
}
public InputStream openStream(String urlAddress) throws MalformedURLException {
URL url = new URL(urlAddress);
while (!proxyList.isEmpty()) {
URLConnection con = null;
try {
con = url.openConnection(proxyList.getNext());
con.setConnectTimeout(6000);
con.setReadTimeout(6000);
return con.getInputStream();
} catch (IOException e) {
proxyList.remove();
}
}
return null;
}
}
All the dependencies of your class to tests are injectable using its constructor, so there shouldn't be any problem to stub these dependencies and injecting the stubs. You don't even need reflection. For example, using Mockito:
NetworkProvider stubbedNetworkProvider = mock(NetworkProvider.class);
MainAPI mainApi = new MainAPI(..., stubbedNetworkProvider);
You can also write a stub by yourself if you want:
NetworkProvider stubbedNetworkProvider = new NetworkProvider(Collections.emptyList()) {
// TODO override the methods to stub
};
MainAPI mainApi = new MainAPI(..., stubbedNetworkProvider);
i have a class which is returning a string type value and i want to return an String array, so please tell how can i able to do that
i have an xml file like resource.xml
<prompts>
<prompt id="p1">welcome to</prompt>
<prompt id ="p2">stack overflow</prompt>
<prompt id="p3">You entered</prompt>
<prompt id="p4">the correct number</prompt>
<prompts>
i am parsing it using sax parser
public class XmlReaderPrompt {
public List<PromptBean> load(String langMode)
{
String fileName="resource.xml";
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
InputStream prompt_configfile=Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
DocumentBuilder db = null;
List<PromptBean> promptMap = new ArrayList<PromptBean>();
try {
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
Document doc = null;
try {
doc = db.parse(prompt_configfile);
}
catch (SAXException e) {
e.printStackTrace();
}
NodeList nodeList=doc.getElementsByTagName("prompt");
for(int i=0;i<nodeList.getLength();i++)
{
Node node=nodeList.item(i);
if(node.getNodeType()==Node.ELEMENT_NODE)
{
Element element=(Element)node;
String id = element.getAttribute("id");
String name = element.getAttribute("name");
String prompt=getTextValue(element);
promptMap.add(new PromptBean(id,name,prompt));
}
}
}
catch(Exception io)
{
io.printStackTrace();
}
finally
{
db=null;
dbf=null;
}
return promptMap;
}
private String getTextValue(Element element) {
String textValue=element.getFirstChild().getTextContent().toString();
return textValue;
}
}
and a UserFunction class to return the text from the xml file
public class UserFunction{
List<PromptBean> promptObject = new ArrayList<PromptBean>();
public String getPromptFunction(String promptTag,String langMode )
{
List<PromptBean> promptObject=xrpObject.load(langMode);
for (Iterator<PromptBean> iterator = promptObject.iterator(); iterator.hasNext();){
PromptBean promptBean= (PromptBean)iterator.next();
if(promptBean.getId().equalsIgnoreCase(promptTag)){
return StringEscapeUtils.escapeXml(promptBean.getPrompt());
}
}
return null;
}
The problem is that I have to call the method getPromptFunction of UserFunction class every time I need to get text from the sub element like
String pr1 = UserFunction.getPromptFunction("p1" "resource");
String pr1 = UserFunction.getPromptFunction("p2" "resource");
String pr1 = UserFunction.getPromptFunction("p3" "resource");
and using it in jsp page as <%=pr1%>
So I want to use array like
String[] pr = UserFunction.getPromptFunction('"p1","p2","p3"' "resource")
So how I am able to do that and also tell how to use it in jsp page .
You can do it like this
public String[] getPromptFunction(String promptTag,String langMode )
{
String temp[] = new String[promptObject.size()];
List<PromptBean> promptObject=xrpObject.load(langMode);
int i = 0;
for (Iterator<PromptBean> iterator = promptObject.iterator(); iterator.hasNext();) {
PromptBean promptBean= (PromptBean)iterator.next();
if(promptBean.getId().equalsIgnoreCase(promptTag)){
temp[i] = StringEscapeUtils.escapeXml(promptBean.getPrompt());
}
i++;
}
return temp;
}
I have a problem with sending ArrayList from server to my client using JAX-rs. I've got 4 classes:
Demo - there is starting REST server
FileDetails - there are 3 fields storing data
ConfigFiles - it has few methods for files and there is a list of FileDetails objects
RestServer - there is method GET
I've got the following code:
#XmlRootElement(name="FileDetails")
#Path("/easy")
public class RestSerwer {
#GET
#Path("/temporary")
#Produces("text/temporary")
public String methodGet() {
ConfigFiles cf = ConfigFiles.getInstance();
List<FileDetails> files = cf.getList();
try {
JAXBContext ctx = JAXBContext.newInstance(ArrayList.class, FileDetails.class);
Marshaller m = ctx.createMarshaller();
StringWriter sw = new StringWriter();
m.marshal(files, sw);
return sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
}
return null;
}
}
At client side I've got GetRest:
public class GetRest{
HttpClient client = null;
GetMethod method = null;
private String url = null;
public GetRest(String url) {
this.url = url;
}
public String getBody(String urlDetail){
client = new HttpClient();
method = new GetMethod(url + urlDetail);
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
client.executeMethod(method);
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
byte[] responseBody = null;
try {
responseBody = method.getResponseBody();
} catch (IOException e) {
e.printStackTrace();
}finally{
method.releaseConnection();
}
String str = new String(responseBody);
return str;
}
public String getFiles(){
return getBody("/easy/temporary");
}
}
When I try:
GetRest getRestClass = new GetRest("http://localhost:8185");
//List<FileDetails> cf = new ArrayList<FileDetails>();
String xxxx = getRestClass.getFiles(); // TODO
It throws:
Caused by: com.sun.istack.internal.SAXException2: unable to marshal type "java.util.ArrayList" as an element because it is missing an #XmlRootElement annotation
At server side.
Anybody can help me?
Thanks
You basically have 2 possibilities: Create you own class which is a wrapper on top of the List or write your own provider and inject it in jersey so that it knows how to marshall/unmarshall the arraylist. Here is a simple code for the first solution:
#XmlRootElement
public class MyListWrapper {
#XmlElement(name = "List")
private List<String> list;
public MyListWrapper() {/*JAXB requires it */
}
public MyListWrapper(List<String> stringList) {
list = stringList;
}
public List<String> getStringList() {
return list;
}
}
I would still need some help with my dynamic selectlist.
I have the sript:
function getMains(element) {
var subjectgroup = element.value;
var select_element;
select_element = '#mains';
$(select_element).html('');
$(select_element).append($("<option></option>").attr("value","none").html(""));
// $(select_element).append($("<option></option>").attr("value","all").html(""));
if (element.value==''||element.value=='none'||element.value=='all')
return;
$.ajax({
type: 'GET',
url: 'getmainsubjects.html',
dataType: 'json',
data: ({id:data}),
success: function(data) {
$.each(function(data) {
if (!subjectgroup) {
$(select_element).append($(" <option>").attr("value",data.id,"items",data).html(data.description));
} else {
$(select_element).append($("<option>").attr("value",data.id,"items",data).html(data.description));
}
});
},
error: function(data) {
//alert("This failed!");
}
});
}
$('select#subjectgroups').ready(function(){
$("select#subjectgroups").find("option").each(function(i) {
if ($(this).val()!='all'&&$(this).val()!='none') {
$(this).append( " " + $(this).val() );
}
});
});
$('select#mains').ready(function(){
$("select#mains").find("option").each(function(i) {
if ($(this).val()!='all'&&$(this).val()!='none') {
$(this).append( " " + $(this).val() );
}
});
});
And the method:
#RequestMapping(method = RequestMethod.GET, params="id", value = "/getmainsubjects")
#ResponseBody
public String getMainSubjects( #RequestParam("id") int id) {
List<MainSubjectsSimple> mains = database.getMainSubjectsSimple(id, Localization.getLanguage());
//System.out.println(mains.size());
HashMap hm = new HashMap();
for (MainSubjectsSimple mss: mains) {
try {
hm.put("id",mss.getId());
hm.put("description", mss.getDescription());
} catch (NoSuchMessageException e) {
//hm.add(Integer.valueOf(mss.getId().toString(), translate(mss.getTranslationCode(),new Locale("fi")));
}
}
String json = null;
String _json = null;
try {
_json = HtmlEntityEncoder.encode(JsonUtils.javaToStr(hm));
} catch (Exception e) {
}
return _json;
}
I think I'm not looping the right values. Mains selectlist should be populated based on other selectlist so that the object's id is the value and description the label. Right now calling the url written in script returns only first object as json, not all of them, and the objects are not shown in mains selectlist.
You are putting the same keys over and over again to the Map hm:
HashMap hm = new HashMap();
for (MainSubjectsSimple mss: mains) {
try {
hm.put("id",mss.getId());
hm.put("description", mss.getDescription());
} catch (NoSuchMessageException e) {
//hm.add(Integer.valueOf(mss.getId().toString(),
translate(mss.getTranslationCode(),new Locale("fi")));
}
}
You need to use different keys for each entry in mains or use a collection (e.g. ArrayList) of Maps. An example of the latter:
List hms = new ArrayList();
for (MainSubjectsSimple mss: mains) {
try {
HashMap hm = new HashMap();
hm.put("id",mss.getId());
hm.put("description", mss.getDescription());
hms.add(hm);
} catch (NoSuchMessageException e) {
//hm.add(Integer.valueOf(mss.getId().toString(), translate(mss.getTranslationCode(),new Locale("fi")));
}
}
...
try {
_json = HtmlEntityEncoder.encode(JsonUtils.javaToStr(hms));
} catch (Exception e) {
}
I'm not familiar with the utils (JsonUtils) you are using so this might not work directly but the principle is the same anyways.