Subversion Repositories SmartDukaan

Rev

Rev 32304 | Rev 32952 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
25380 amit.gupta 1
package com.spice.profitmandi.web.controller;
2
 
3
import com.google.gson.Gson;
30080 amit.gupta 4
import com.jcraft.jsch.*;
25380 amit.gupta 5
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
6
import com.spice.profitmandi.common.solr.SolrService;
7
import com.spice.profitmandi.dao.entity.catalog.Item;
28264 tejbeer 8
import com.spice.profitmandi.dao.entity.dtr.DocumentUrl;
25380 amit.gupta 9
import com.spice.profitmandi.dao.model.ContentPojo;
10
import com.spice.profitmandi.dao.model.MediaPojo;
11
import com.spice.profitmandi.dao.model.Specification;
12
import com.spice.profitmandi.dao.model.SpecificationGroup;
31330 tejbeer 13
import com.spice.profitmandi.dao.repository.catalog.FocusedModelRepository;
25380 amit.gupta 14
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
28264 tejbeer 15
import com.spice.profitmandi.dao.repository.dtr.DocumentUrlRepository;
25380 amit.gupta 16
import com.spice.profitmandi.dao.repository.dtr.Mongo;
17
import com.spice.profitmandi.web.model.EntityMediaPojo;
18
import com.spice.profitmandi.web.util.MVCResponseSender;
30080 amit.gupta 19
import org.apache.commons.csv.CSVFormat;
20
import org.apache.commons.csv.CSVParser;
21
import org.apache.commons.csv.CSVRecord;
22
import org.apache.commons.lang3.StringUtils;
23
import org.apache.logging.log4j.LogManager;
24
import org.apache.logging.log4j.Logger;
31330 tejbeer 25
import org.json.JSONArray;
26
import org.json.JSONObject;
30080 amit.gupta 27
import org.springframework.beans.factory.annotation.Autowired;
28
import org.springframework.stereotype.Controller;
29
import org.springframework.ui.Model;
30
import org.springframework.web.bind.annotation.*;
31
import org.springframework.web.multipart.MultipartFile;
25380 amit.gupta 32
 
30080 amit.gupta 33
import javax.servlet.http.HttpServletRequest;
34
import javax.transaction.Transactional;
35
import javax.xml.bind.DatatypeConverter;
36
import java.io.*;
37
import java.sql.Timestamp;
38
import java.time.LocalDate;
39
import java.time.LocalDateTime;
40
import java.time.ZoneOffset;
41
import java.util.*;
42
import java.util.stream.Collectors;
43
 
25380 amit.gupta 44
@Transactional(rollbackOn = Throwable.class)
45
@Controller
46
public class ContentController {
47
	@Autowired
48
	MVCResponseSender mvcResponseSender;
49
 
50
	@Autowired
51
	Mongo mongoClient;
52
 
53
	@Autowired
54
	SolrService solrService;
55
 
56
	@Autowired
57
	ItemRepository itemRepository;
58
 
28264 tejbeer 59
	@Autowired
60
	DocumentUrlRepository documentUrlRepository;
61
 
31330 tejbeer 62
	@Autowired
63
	FocusedModelRepository focusedModelRepository;
25380 amit.gupta 64
	private Gson gson = new Gson();
65
 
66
	public static final int Entity_Id = 0;
67
	public static final int Title = 1;
68
	public static final int KeySpec1 = 2;
69
	public static final int KeySpec2 = 3;
70
	public static final int KeySpec3 = 4;
71
	public static final int KeySpec4 = 5;
72
	public static final int Warranty = 6;
73
	public static final int Package_Contents = 7;
28264 tejbeer 74
	private static final String IMAGE_REMOTE_DIR = "/var/www/dtrdashboard/uploads/campaigns/";
75
	private static final String IMAGE_STATIC_SERVER_URL = "https://images.smartdukaan.com/uploads/campaigns";
25380 amit.gupta 76
 
29900 amit.gupta 77
	private static final String REMOTE_DIR = "/var/www/static.saholic.com/images/media/";
31330 tejbeer 78
	// private static final String REMOTE_DIR = "/tmp";
25986 amit.gupta 79
	private static final String STATIC_SERVER_URL = "https://static%d.smartdukaan.com/images/media/";
25380 amit.gupta 80
 
81
	private static final String THUMBNAIL = "thumbnail";
82
	private static final String ICON = "icon";
83
	private static final String DEFAULT = "default";
84
	private static final String NONE = "";
25409 amit.gupta 85
 
25400 amit.gupta 86
	private static final Logger LOGGER = LogManager.getLogger(ContentController.class);
25380 amit.gupta 87
 
88
	private String getFileName(int entityId, String description, String extension) {
89
		List<Item> items = itemRepository.selectAllByCatalogItemId(entityId);
25409 amit.gupta 90
		String imageString = getMediaPrefix(items.get(0).getItemDescriptionNoColor() + " " + description) + "-"
25380 amit.gupta 91
				+ LocalDateTime.now().toEpochSecond(ZoneOffset.ofHoursMinutes(5, 30));
25413 amit.gupta 92
		return imageString + "." + extension;
25380 amit.gupta 93
	}
94
 
95
	@PostMapping(value = "/content/upload")
96
	public String uploadContent(HttpServletRequest request, @RequestPart("file") MultipartFile file, Model model)
97
			throws Exception {
98
		List<ContentPojo> contentPojos = readFile(file);
99
		for (ContentPojo contentPojo : contentPojos) {
100
			mongoClient.persistEntity(contentPojo);
101
		}
31238 amit.gupta 102
		model.addAttribute("response1", mvcResponseSender.createResponseString(true));
25380 amit.gupta 103
		return "response";
104
	}
105
 
106
	@PostMapping(value = "/content/media/upload")
107
	public String uploadMediaContent(HttpServletRequest request, @RequestBody EntityMediaPojo entityMediaPojo,
108
			Model model) throws Exception {
109
		ContentPojo contentPojo = mongoClient.getEntityById(entityMediaPojo.getEntityId());
110
		Map<String, InputStream> fileStreamsMap = getStreamFileMap(contentPojo, entityMediaPojo);
25400 amit.gupta 111
		LOGGER.info("fileStreamsMap {}, " + fileStreamsMap.keySet());
29900 amit.gupta 112
		uploadContentFiles(fileStreamsMap, entityMediaPojo.getEntityId());
25380 amit.gupta 113
		mongoClient.persistEntity(contentPojo);
31238 amit.gupta 114
		model.addAttribute("response1", mvcResponseSender.createResponseString(true));
25380 amit.gupta 115
		return "response";
116
	}
117
 
28264 tejbeer 118
	@PostMapping(value = "/image/media/upload")
119
	public String uploadImageMediaContent(HttpServletRequest request, @RequestBody MediaPojo mediaPojo, Model model)
120
			throws Exception {
121
 
122
		LOGGER.info("mediaPojo" + mediaPojo);
123
		Map<String, InputStream> fileStreamsMap = new HashMap<>();
124
		String extension;
125
		String base64String = mediaPojo.getImageData();
126
		String[] strings = base64String.split(",");
127
		switch (strings[0]) {// check image's extension
128
		case "data:image/jpeg;base64":
129
			extension = "jpeg";
130
			break;
131
		case "data:image/png;base64":
132
			extension = "png";
133
			break;
32304 amit.gupta 134
			case "data:image/webp;base64":
32305 amit.gupta 135
				extension = "webp";
32304 amit.gupta 136
				break;
28264 tejbeer 137
		default:// should write cases for more images types
32304 amit.gupta 138
			extension = "jpg";
28264 tejbeer 139
			break;
140
		}
141
		LOGGER.info("After switch statement = {}", extension);
142
		// convert base64 string to binary data
143
		byte[] data = DatatypeConverter.parseBase64Binary(strings[1]);
144
		Timestamp tm = new Timestamp(System.currentTimeMillis());
28320 tejbeer 145
		String urlTitle = mediaPojo.getTitle().toLowerCase();
146
		String fileName = urlTitle.replace(' ', '-') + tm.getTime() + "." + extension;
28264 tejbeer 147
		LOGGER.info("After switch statement Filename = {}", fileName);
148
		mediaPojo.setImageData(null);
149
		mediaPojo.setUrl(IMAGE_STATIC_SERVER_URL + "/" + "image" + LocalDate.now() + "/" + fileName);
150
		fileStreamsMap.put(fileName, new ByteArrayInputStream(data));
151
		LOGGER.info("fileStreamsMap" + fileStreamsMap);
152
 
153
		uploadFile(fileStreamsMap);
154
 
155
		DocumentUrl du = new DocumentUrl();
156
		du.setTitle(mediaPojo.getTitle());
157
		du.setUrl(mediaPojo.getUrl());
158
		du.setCreatedTimestamp(LocalDateTime.now());
159
		documentUrlRepository.persist(du);
160
 
161
		model.addAttribute("documents", du);
162
		return "image-url";
163
	}
164
 
165
	private void fileUpload(ChannelSftp channelSftp, Map<String, InputStream> streamsFileMap, String destinationPath)
166
			throws SftpException, FileNotFoundException {
167
 
168
		channelSftp.cd(destinationPath);
169
		String folderName = "image" + LocalDate.now();
170
 
171
		channelSftp.cd(destinationPath);
172
		SftpATTRS attrs = null;
173
 
174
		// check if the directory is already existing
175
		try {
176
			attrs = channelSftp.stat(folderName);
177
		} catch (Exception e) {
178
			System.out.println(destinationPath + "/" + "image" + LocalDate.now() + " not found");
179
		}
180
 
181
		// else create a directory
182
		if (attrs == null) {
183
			channelSftp.mkdir(folderName);
184
			channelSftp.chmod(0755, ".");
185
		}
186
		channelSftp.cd(folderName);
187
 
188
		for (Map.Entry<String, InputStream> streamsFileEntry : streamsFileMap.entrySet()) {
189
			channelSftp.put(streamsFileEntry.getValue(), streamsFileEntry.getKey(), ChannelSftp.OVERWRITE);
190
		}
191
 
192
	}
193
 
194
	@GetMapping(value = "/search/image/media")
195
	public String getImage(HttpServletRequest request, Model model, @RequestParam String title) throws Exception {
196
		List<DocumentUrl> documents = documentUrlRepository.selectBySearch(title);
197
 
198
		model.addAttribute("documents", documents);
199
		return "image-url";
200
 
201
	}
202
 
25380 amit.gupta 203
	@GetMapping(value = "/content/media")
204
	public String getMediaContent(HttpServletRequest request, Model model, @RequestParam int entityId)
205
			throws Exception {
206
		ContentPojo contentPojo = mongoClient.getEntityById(entityId);
25409 amit.gupta 207
		if (contentPojo == null) {
25380 amit.gupta 208
			throw new Exception("Please add content first");
209
		}
210
		EntityMediaPojo empojo = getEntityMediaPojo(contentPojo);
31238 amit.gupta 211
		model.addAttribute("response1", mvcResponseSender.createResponseString(empojo));
25380 amit.gupta 212
		return "response";
213
	}
28264 tejbeer 214
 
27185 amit.gupta 215
	@GetMapping(value = "/catalog-item")
28264 tejbeer 216
	public String catalogItem(HttpServletRequest request, Model model) throws Exception {
27185 amit.gupta 217
		return "catalog-item";
218
	}
25380 amit.gupta 219
 
220
	private EntityMediaPojo getEntityMediaPojo(ContentPojo contentPojo) {
221
		EntityMediaPojo ep = new EntityMediaPojo();
222
		int defaultIndex = 0;
25409 amit.gupta 223
		if (contentPojo.getImages() == null) {
25380 amit.gupta 224
			ep.setMediaPojos(new ArrayList<>());
225
		} else {
226
			ep.setMediaPojos(contentPojo.getImages());
227
			for (MediaPojo mediaPojo : contentPojo.getImages()) {
25409 amit.gupta 228
				if (mediaPojo.getUrl() == null)
229
					continue;
230
 
25380 amit.gupta 231
				if (!mediaPojo.getUrl().equals(contentPojo.getDefaultImageUrl())) {
232
					defaultIndex++;
233
				}
234
			}
235
		}
236
		ep.setDefaultImageIndex(defaultIndex);
237
		return ep;
238
	}
239
 
240
	@GetMapping(value = "/entity")
28264 tejbeer 241
	public String searchEntity(HttpServletRequest request, @RequestParam(defaultValue = "null") String query,
31330 tejbeer 242
			@RequestParam(defaultValue = "0") int categoryId, @RequestParam(defaultValue = "") List<String> brands,
243
			@RequestParam(defaultValue = "30") int limit, @RequestParam(defaultValue = "true") boolean activeOnly,
244
			Model model) throws Exception {
245
		model.addAttribute("response1", solrService.getContent(query, categoryId > 0 ? Arrays.asList(categoryId) : null,
31711 amit.gupta 246
				brands, limit, false));
25380 amit.gupta 247
		return "response";
248
	}
249
 
31330 tejbeer 250
	@GetMapping(value = "/focusedEntity")
251
	public String focusedEntity(HttpServletRequest request, @RequestParam(defaultValue = "null") String query,
252
			@RequestParam(defaultValue = "0") int categoryId, @RequestParam(defaultValue = "") List<String> brands,
253
			@RequestParam(defaultValue = "30") int limit, @RequestParam(defaultValue = "true") boolean activeOnly,
254
			Model model) throws Exception {
255
 
256
		List<Integer> catalogIds = focusedModelRepository.selectAll().stream().map(x -> x.getCatalogId())
257
				.collect(Collectors.toList());
258
		JSONArray docA = solrService.getContentDocs(query, categoryId > 0 ? Arrays.asList(categoryId) : null, brands,
259
				limit, activeOnly);
260
 
261
		Iterator<Object> jsonIterator = docA.iterator();
262
		while (jsonIterator.hasNext()) {
263
			JSONObject i = (JSONObject) jsonIterator.next();
264
 
265
			if (!catalogIds.contains(i.get("catalogId_i"))) {
266
				jsonIterator.remove();
267
			}
268
 
269
		}
270
 
271
		model.addAttribute("response1", docA.toString());
272
 
273
		return "response";
274
	}
275
 
25380 amit.gupta 276
	@GetMapping(value = "/content/index")
277
	public String index(HttpServletRequest request, Model model) throws Exception {
278
		return "content";
279
	}
280
 
281
	private List<ContentPojo> readFile(MultipartFile file) throws Exception {
282
		CSVParser parser = new CSVParser(new InputStreamReader(file.getInputStream()), CSVFormat.DEFAULT);
283
		List<CSVRecord> records = parser.getRecords();
284
		if (records.size() < 2) {
285
			parser.close();
286
			throw new ProfitMandiBusinessException("Uploaded File", "", "No records Found");
287
		}
288
		// Remove header
289
		records.remove(0);
290
		List<ContentPojo> returnList = new ArrayList<ContentPojo>();
291
		for (CSVRecord record : records) {
25430 amit.gupta 292
			ContentPojo cp = null;
293
			Long entityId = Long.parseLong(record.get(Entity_Id));
25380 amit.gupta 294
			try {
25430 amit.gupta 295
				cp = mongoClient.getEntityById(entityId);
296
			} catch (Exception e) {
297
			}
298
			try {
299
				if (cp == null) {
300
					cp = new ContentPojo(entityId);
301
				}
25380 amit.gupta 302
				cp.setWarranty(record.get(Warranty));
303
				cp.setKeySpecs(Arrays
304
						.asList(record.get(KeySpec1), record.get(KeySpec2), record.get(KeySpec3), record.get(KeySpec4))
25429 amit.gupta 305
						.stream().filter(x -> x != null && !x.equals("")).collect(Collectors.toList()));
25380 amit.gupta 306
				cp.setPackageContents(Arrays.asList(record.get(Package_Contents).split(",")));
307
				cp.setDetailedSpecs(getDetailedSpecs(record));
308
				returnList.add(cp);
309
			} catch (Exception e) {
310
				continue;
311
			}
312
		}
313
		parser.close();
314
		return returnList;
315
	}
316
 
317
	private List<SpecificationGroup> getDetailedSpecs(CSVRecord record) throws Exception {
318
		List<SpecificationGroup> specificationGroups = new ArrayList<>();
319
		int currentIndex = 8;
320
		while (StringUtils.isNotEmpty(record.get(currentIndex))) {
321
			int start = currentIndex;
322
			List<Specification> specifications = new ArrayList<>();
323
			int begin = 0;
324
			while (begin < 5) {
325
				int specKeyIndex = (begin * 2) + 1;
326
				int specValueIndex = (begin * 2) + 2;
327
 
328
				if (StringUtils.isNotEmpty(record.get(currentIndex + specKeyIndex))
329
						&& StringUtils.isNotEmpty(record.get(currentIndex + specValueIndex))) {
330
					Specification specification = new Specification(record.get(currentIndex + specKeyIndex),
331
							Arrays.asList(record.get(currentIndex + specValueIndex)));
332
					specifications.add(specification);
333
				}
334
				begin++;
335
			}
336
			SpecificationGroup specificationGroup = new SpecificationGroup(record.get(start), specifications);
337
			specificationGroups.add(specificationGroup);
25392 amit.gupta 338
			currentIndex += 11;
25380 amit.gupta 339
		}
340
 
341
		return specificationGroups;
342
	}
343
 
344
	private ChannelSftp setupJsch() throws JSchException {
345
		JSch jsch = new JSch();
28266 tejbeer 346
		Session jschSession = jsch.getSession("root", "192.168.179.131");
31330 tejbeer 347
		// Session jschSession = jsch.getSession("root", "173.255.254.24");
348
		LOGGER.info("getClass().getResource(\"id_rsa\") {}",
349
				getClass().getClassLoader().getResource("id_rsa").getPath());
29881 amit.gupta 350
		jsch.addIdentity(getClass().getClassLoader().getResource("id_rsa").getPath());
31330 tejbeer 351
		// jschSession.setPassword("spic@2015static0");
25396 amit.gupta 352
		jschSession.setConfig("StrictHostKeyChecking", "no");
25380 amit.gupta 353
		jschSession.connect();
354
		return (ChannelSftp) jschSession.openChannel("sftp");
355
	}
356
 
29900 amit.gupta 357
	private void uploadFile(Map<String, InputStream> fileStreamsMap) throws Exception {
25380 amit.gupta 358
		ChannelSftp channelSftp = setupJsch();
359
		channelSftp.connect();
29900 amit.gupta 360
		this.fileUpload(channelSftp, fileStreamsMap, IMAGE_REMOTE_DIR + "");
361
		channelSftp.exit();
362
	}
363
 
364
	private void uploadContentFiles(Map<String, InputStream> fileStreamsMap, int entityId) throws Exception {
365
		ChannelSftp channelSftp = setupJsch();
366
		channelSftp.connect();
25380 amit.gupta 367
		this.folderUpload(channelSftp, fileStreamsMap, REMOTE_DIR, entityId + "");
368
		channelSftp.exit();
369
	}
370
 
371
	private void recursiveFolderUpload(ChannelSftp channelSftp, String sourcePath, String destinationPath)
372
			throws SftpException, FileNotFoundException {
373
 
374
		File sourceFile = new File(sourcePath);
375
		if (sourceFile.isFile()) {
376
 
377
			// copy if it is a file
378
			channelSftp.cd(destinationPath);
379
			if (!sourceFile.getName().startsWith("."))
380
				channelSftp.put(new FileInputStream(sourceFile), sourceFile.getName(), ChannelSftp.OVERWRITE);
381
 
382
		} else {
383
 
384
			System.out.println("inside else " + sourceFile.getName());
385
			File[] files = sourceFile.listFiles();
386
 
387
			if (files != null && !sourceFile.getName().startsWith(".")) {
388
 
389
				channelSftp.cd(destinationPath);
390
				SftpATTRS attrs = null;
391
 
392
				// check if the directory is already existing
393
				try {
394
					attrs = channelSftp.stat(destinationPath + "/" + sourceFile.getName());
395
				} catch (Exception e) {
396
					System.out.println(destinationPath + "/" + sourceFile.getName() + " not found");
397
				}
398
 
399
				// else create a directory
400
				if (attrs != null) {
401
					System.out.println("Directory exists IsDir=" + attrs.isDir());
402
				} else {
403
					System.out.println("Creating dir " + sourceFile.getName());
404
					channelSftp.mkdir(sourceFile.getName());
405
				}
406
 
407
				for (File f : files) {
408
					recursiveFolderUpload(channelSftp, f.getAbsolutePath(),
409
							destinationPath + "/" + sourceFile.getName());
410
				}
411
 
412
			}
413
		}
414
 
415
	}
416
 
417
	private void folderUpload(ChannelSftp channelSftp, Map<String, InputStream> streamsFileMap, String destinationPath,
418
			String folderName) throws SftpException, FileNotFoundException {
419
 
420
		channelSftp.cd(destinationPath);
421
		SftpATTRS attrs = null;
422
 
423
		// check if the directory is already existing
424
		try {
425
			attrs = channelSftp.stat(folderName);
426
		} catch (Exception e) {
427
			System.out.println(destinationPath + "/" + folderName + " not found");
428
		}
429
 
430
		// else create a directory
25413 amit.gupta 431
		if (attrs == null) {
432
			channelSftp.mkdir(folderName);
433
			channelSftp.chmod(0755, ".");
25380 amit.gupta 434
		}
435
		channelSftp.cd(folderName);
25413 amit.gupta 436
		channelSftp.rm("*");
25380 amit.gupta 437
 
438
		for (Map.Entry<String, InputStream> streamsFileEntry : streamsFileMap.entrySet()) {
439
			channelSftp.put(streamsFileEntry.getValue(), streamsFileEntry.getKey(), ChannelSftp.OVERWRITE);
440
		}
441
 
442
	}
443
 
444
	private Map<String, InputStream> getStreamFileMap(ContentPojo contentPojo, EntityMediaPojo entityMediaPojo) {
445
		Map<String, InputStream> map = new HashMap<>();
25401 amit.gupta 446
		LOGGER.info("entityMediaPojo.getMediaPojos() -[{}]", entityMediaPojo.getMediaPojos());
25404 amit.gupta 447
		for (int i = 0; i < entityMediaPojo.getMediaPojos().size(); i++) {
25380 amit.gupta 448
			MediaPojo mediaPojo = entityMediaPojo.getMediaPojos().get(i);
449
			String extension;
450
			String base64String = mediaPojo.getImageData();
451
			String[] strings = base64String.split(",");
452
			switch (strings[0]) {// check image's extension
453
			case "data:image/jpeg;base64":
454
				extension = "jpeg";
455
				break;
456
			case "data:image/png;base64":
457
				extension = "png";
458
				break;
459
			default:// should write cases for more images types
460
				extension = "jpg";
461
				break;
462
			}
25402 amit.gupta 463
			LOGGER.info("After switch statement = {}", extension);
25380 amit.gupta 464
			// convert base64 string to binary data
465
			byte[] data = DatatypeConverter.parseBase64Binary(strings[1]);
466
			String fileName = getFileName(entityMediaPojo.getEntityId(), mediaPojo.getTitle(), extension);
25402 amit.gupta 467
			LOGGER.info("After switch statement Filename = {}", fileName);
25380 amit.gupta 468
			mediaPojo.setImageData(null);
25430 amit.gupta 469
			String staticServerUrl = String.format(STATIC_SERVER_URL, entityMediaPojo.getEntityId() % 3);
25414 amit.gupta 470
			mediaPojo.setUrl(staticServerUrl + entityMediaPojo.getEntityId() + "/" + fileName);
25380 amit.gupta 471
			map.put(fileName, new ByteArrayInputStream(data));
472
			if (i == entityMediaPojo.getDefaultImageIndex()) {
473
				String defaultFileName = getFileName(entityMediaPojo.getEntityId(), DEFAULT, extension);
474
				map.put(defaultFileName, new ByteArrayInputStream(data));
25414 amit.gupta 475
				contentPojo.setDefaultImageUrl(staticServerUrl + entityMediaPojo.getEntityId() + "/" + defaultFileName);
25380 amit.gupta 476
			}
477
		}
478
		contentPojo.setImages(entityMediaPojo.getMediaPojos());
479
 
480
		return map;
481
	}
482
 
25409 amit.gupta 483
	private String getMediaPrefix(String productName) {
484
		String mediaPrefix = productName.toLowerCase().replace(' ', '-');
485
		mediaPrefix = mediaPrefix.replaceAll("/", "-");
486
		mediaPrefix = mediaPrefix.replaceAll("-+", "-");
487
		return mediaPrefix;
488
	}
489
 
28264 tejbeer 490
	@GetMapping(value = "/urlGeneration")
491
	public String urlGeneration(HttpServletRequest request, Model model) throws Exception {
492
		return "url-generation";
493
	}
25380 amit.gupta 494
}