Merge "The second patch of an estimated 4 to complete the COPS message refactoring...
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / messages / impl / MessageFactory.java
1 /**
2  * @header@
3  */
4 package org.pcmm.messages.impl;
5
6 import org.pcmm.messages.IMessage.MessageProperties;
7 import org.pcmm.messages.IMessageFactory;
8 import org.pcmm.objects.MMVersionInfo;
9 import org.pcmm.rcd.ICMTS;
10 import org.pcmm.rcd.IPCMMClient;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.umu.cops.stack.*;
14 import org.umu.cops.stack.COPSClientSI.CSIType;
15 import org.umu.cops.stack.COPSContext.RType;
16 import org.umu.cops.stack.COPSDecision.Command;
17 import org.umu.cops.stack.COPSDecision.DecisionFlag;
18 import org.umu.cops.stack.COPSError.ErrorTypes;
19
20 import java.net.InetAddress;
21 import java.util.Properties;
22
23 /**
24  *
25  *
26  */
27 public class MessageFactory implements IMessageFactory {
28
29     /** Default keep-alive timer value (secs) */
30     public static final short KA_TIMER_VALUE = 30;
31     /** Default accounting timer value (secs) */
32     public static final short ACCT_TIMER_VALUE = 0;
33
34     private static final Logger logger = LoggerFactory.getLogger(MessageFactory.class);
35
36     private static final MessageFactory instance = new MessageFactory();
37
38     private MessageFactory() {
39     }
40
41     public static MessageFactory getInstance() {
42         return instance;
43     }
44
45     /*
46      * (non-Javadoc)
47      *
48      * @see pcmm.messages.IMessageFactory#create(pcmm.messages.MessageType)
49      */
50     public COPSMsg create(final byte messageType) {
51         return create(messageType, new Properties());
52     }
53
54     /*
55      * (non-Javadoc)
56      *
57      * @see org.pcmm.messages.IMessageFactory#create(org.pcmm.messages.IMessage.
58      * MessageType, java.util.Properties)
59      */
60     public COPSMsg create(final byte messageType, final Properties properties) {
61         logger.info("Creating message of type - " + messageType);
62         // return new PCMMMessage(messageType, content);
63         switch (messageType) {
64             case COPSHeader.COPS_OP_OPN:
65                 return createOPNMessage(properties);
66             case COPSHeader.COPS_OP_REQ:
67                 return createREQMessage(properties);
68             case COPSHeader.COPS_OP_CAT:
69                 return createCATMessage(properties);
70             case COPSHeader.COPS_OP_CC:
71                 return createCCMessage(properties);
72             case COPSHeader.COPS_OP_DEC:
73                 return createDECMessage(properties);
74             case COPSHeader.COPS_OP_DRQ:
75                 break;
76             case COPSHeader.COPS_OP_KA:
77                 return createKAMessage(properties);
78             case COPSHeader.COPS_OP_RPT:
79                 break;
80             case COPSHeader.COPS_OP_SSC:
81                 break;
82             case COPSHeader.COPS_OP_SSQ:
83                 break;
84         }
85         return null;
86     }
87
88     /**
89      *
90      * @param prop - the properties
91      * @return - the message
92      */
93     protected COPSMsg createDECMessage(final Properties prop) {
94         final COPSDecisionMsg msg = new COPSDecisionMsg();
95         // ===common part between all gate control messages
96         final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, IPCMMClient.CLIENT_TYPE);
97         // handle
98         // context
99         final COPSContext context = new COPSContext(RType.CONFIG, (short) 0);
100         // decision
101
102         Command cmd = null;
103         if (prop.get(MessageProperties.DECISION_CMD_CODE) != null)
104             cmd = (Command) prop.get(MessageProperties.DECISION_CMD_CODE);
105
106         DecisionFlag flag = null;
107         if (prop.get(MessageProperties.DECISION_FLAG) != null)
108             flag = (DecisionFlag) prop.get(MessageProperties.DECISION_FLAG);
109
110         final COPSDecision decision = new COPSDecision(cmd, flag);
111
112         COPSData data = null;
113         if (prop.get(MessageProperties.GATE_CONTROL) != null)
114             data = (COPSData) prop.get(MessageProperties.GATE_CONTROL);
115
116         // TODO - Determine the proper type here.
117         final COPSClientSI si = new COPSClientSI(CSIType.SIGNALED, data);
118         try {
119             msg.add(hdr);
120             final COPSHandle handle;
121             if (prop.get(MessageProperties.CLIENT_HANDLE) != null) {
122                 handle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
123             }
124             else {
125                 // TODO - This smells wrong to have a null handle ID
126                 handle = new COPSHandle(null);
127             }
128             msg.add(handle);
129             msg.addDecision(decision, context);
130             msg.add(si);
131
132             // TODO - determine why this block has been commented out
133             // try {
134             // msg.dump(System.out);
135             // } catch (IOException unae) {
136             // }
137
138         } catch (final COPSException e) {
139             logger.error(e.getMessage());
140         }
141
142         return msg;
143     }
144
145     /**
146      * creates a Client-Open message.
147      *
148      * @param prop
149      *            properties
150      * @return COPS message
151      */
152     protected COPSMsg createOPNMessage(final Properties prop) {
153         final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, IPCMMClient.CLIENT_TYPE);
154         // version infor object
155         short majorVersion = MMVersionInfo.DEFAULT_MAJOR_VERSION_INFO;
156         short minorVersion = MMVersionInfo.DEFAULT_MINOR_VERSION_INFO;
157         if (prop.get(MessageProperties.MM_MAJOR_VERSION_INFO) != null)
158             majorVersion = (Short) prop.get(MessageProperties.MM_MAJOR_VERSION_INFO);
159         if (prop.get(MessageProperties.MM_MINOR_VERSION_INFO) != null)
160             minorVersion = (Short) prop.get(MessageProperties.MM_MINOR_VERSION_INFO);
161         // Mandatory MM version.
162         byte[] versionInfo = new MMVersionInfo(majorVersion, minorVersion).getAsBinaryArray();
163         final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED,
164                 new COPSData(versionInfo, 0, versionInfo.length));
165         final COPSClientOpenMsg msg = new COPSClientOpenMsg();
166         try {
167             final COPSData d;
168             if (prop.get(MessageProperties.PEP_ID) != null)
169                 d = new COPSData((String) prop.get(MessageProperties.PEP_ID));
170             else
171                 d = new COPSData(InetAddress.getLocalHost().getHostName());
172             final COPSPepId pepId = new COPSPepId(d);
173             msg.add(hdr);
174             msg.add(pepId);
175             msg.add(clientSI);
176         } catch (Exception e) {
177             logger.error("Error creating OPN message", e);
178         }
179         return msg;
180     }
181
182     /**
183      * creates a Client-Accept message.
184      * @param prop - properties
185      * @return COPS message
186      */
187     protected COPSMsg createCATMessage(final Properties prop) {
188         final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_CAT, IPCMMClient.CLIENT_TYPE);
189         final COPSKATimer katimer;
190         if (prop.get(MessageProperties.KA_TIMER) != null)
191             katimer = new COPSKATimer((short) prop.get(MessageProperties.KA_TIMER));
192         else
193             katimer = new COPSKATimer(KA_TIMER_VALUE);
194
195         final COPSAcctTimer acctTimer;
196         if (prop.get(MessageProperties.ACCEPT_TIMER) != null)
197             acctTimer = new COPSAcctTimer((short) prop.get(MessageProperties.ACCEPT_TIMER));
198         else
199             acctTimer = new COPSAcctTimer(ACCT_TIMER_VALUE);
200
201         final COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
202         try {
203             acceptMsg.add(hdr);
204             acceptMsg.add(katimer);
205             if (acctTimer.getTimerVal() != 0)
206                 acceptMsg.add(acctTimer);
207         } catch (COPSException e) {
208             logger.error(e.getMessage());
209         }
210         return acceptMsg;
211     }
212
213     /**
214      * creates a Client-Close message.
215      *
216      * @param prop
217      *            properties
218      * @return COPS message
219      */
220     protected COPSMsg createCCMessage(final Properties prop) {
221         final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, IPCMMClient.CLIENT_TYPE);
222         final COPSError err;
223         if (prop.get(MessageProperties.ERR_MESSAGE) != null) {
224             ErrorTypes code = ErrorTypes.NA;
225             final ErrorTypes error = (ErrorTypes) prop.get(MessageProperties.ERR_MESSAGE);
226             if (prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE) != null)
227                 code = (ErrorTypes) prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE);
228             err = new COPSError(error, code);
229         } else
230             err = new COPSError(ErrorTypes.UNKNOWN, ErrorTypes.NA);
231
232         final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
233         try {
234             closeMsg.add(cHdr);
235             closeMsg.add(err);
236         } catch (COPSException e) {
237             logger.error(e.getMessage());
238         }
239         return closeMsg;
240     }
241
242     /**
243      * creates a Request message
244      *
245      * @param prop
246      *            properties
247      * @return Request message
248      */
249     protected COPSMsg createREQMessage(final Properties prop) {
250         final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_REQ, IPCMMClient.CLIENT_TYPE);
251         final COPSReqMsg req = new COPSReqMsg();
252
253         final RType rType;
254         if (prop.get(MessageProperties.R_TYPE) != null)
255             rType = (RType) prop.get(MessageProperties.R_TYPE);
256         else rType = RType.NA; //ICMTS.DEFAULT_R_TYPE;
257
258         final short mType;
259         if (prop.get(MessageProperties.M_TYPE) != null)
260             mType = (Short) prop.get(MessageProperties.M_TYPE);
261         else mType = ICMTS.DEFAULT_M_TYPE;
262
263         final COPSContext copsContext = new COPSContext(rType, mType);
264         final COPSHandle copsHandle;
265         if (prop.get(MessageProperties.CLIENT_HANDLE) != null)
266             copsHandle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
267         else
268             // just a random handle
269             copsHandle = new COPSHandle(new COPSData("" + Math.random() * 82730));
270         try {
271             req.add(cHdr);
272             req.add(copsContext);
273             req.add(copsHandle);
274         } catch (COPSException e) {
275             logger.error(e.getMessage());
276         }
277         return req;
278     }
279
280     /**
281      * creates a Keep-Alive message.
282      *
283      * @param prop
284      *            properties
285      * @return COPS message
286      * TODO - Why is there a timer being instantiated but never used?
287      */
288     protected COPSMsg createKAMessage(final Properties prop) {
289         final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_KA, (short) 0);
290         final COPSKAMsg kaMsg = new COPSKAMsg();
291         final COPSKATimer timer;
292         if (prop.get(MessageProperties.KA_TIMER) != null)
293             timer = new COPSKATimer((Short) prop.get(MessageProperties.KA_TIMER));
294         else
295             timer = new COPSKATimer((short)1);
296         try {
297             kaMsg.add(cHdr);
298         } catch (COPSException e) {
299             logger.error(e.getMessage());
300         }
301         return kaMsg;
302     }
303 }